React Child componentDidMount不在Route上触发
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了React Child componentDidMount不在Route上触发相关的知识,希望对你有一定的参考价值。
我是React的新手,一直在寻找用无头WP后端构建我的第一个反应应用程序。
我无法让componentDidMount
在我的MoviePage
课程中触发。我希望有人能帮我理解我做错了什么。
这是我的代码,它可能不完美,因为这是我的第一次尝试。
注意代码现在已经改变了添加注释的建议 - 检查原始代码的编辑历史(它仍然被破坏)
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom';
import './index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';
ReactDOM.render((
<BrowserRouter>
<App />
</BrowserRouter>
),
document.getElementById('root'));
registerServiceWorker();
App.js
import React from 'react';
import Header from './components/Header';
import Main from './components/Main';
class App extends React.Component {
render() {
return (
<div>
<Header />
<Main />
</div>
)
}
}
export default App;
Header.js
import React from 'react';
import { Link } from "react-router-dom";
class Header extends React.Component {
constructor() {
super();
this.state = {
movies: []
}
}
componentDidMount() {
let dataURL = "http://localhost:8888/SBP/website/wp-json/wp/v2/movies?_embed";
fetch(dataURL)
.then(response => response.json())
.then(response => {
this.setState({
movies: response
})
})
}
render() {
let movieLinks = this.state.movies.map((movie, index) => {
return <li key={index}><Link to={'/movies/'+movie.id}>{movie.title.rendered}</Link></li>
});
return (
<header>
<nav>
<ul>
<li><Link to='/movies'>All Movies</Link></li>
{movieLinks}
</ul>
</nav>
</header>
)
}
}
export default Header;
Main.js
import React from 'react';
import { Route } from "react-router-dom";
import Movies from './Movies';
class Main extends React.Component {
render() {
return (
<main>
<Route path='/movies' component={Movies}/>
</main>
)
}
}
export default Main;
Movies.js
import React from 'react';
import { Switch, Route, } from "react-router-dom";
import MoviesHub from './MoviesHub';
import MoviePage from './MoviePage';
class Movies extends React.Component {
render() {
return (
<Switch>
<Route exact path='/movies' component={MoviesHub}/>
<Route path='/movies/:number' component={MoviePage}/>
</Switch>
)
}
}
export default Movies;
MoviesHub.js
import React from 'react';
class MoviesHub extends React.Component {
constructor() {
super();
this.state = {
movies: []
}
}
componentDidMount() {
let dataURL = "http://localhost:8888/SBP/website/wp-json/wp/v2/movies?_embed";
fetch(dataURL)
.then(res => res.json())
.then(res => {
this.setState({
movies: res
})
})
}
render() {
let movies = this.state.movies.map((movie, index) => {
return <div key={index}>
<img src={movie._embedded['wp:featuredmedia'][0].media_details.sizes.large.source_url} alt={movie.title.rendered} />
<p><strong>Title:</strong> {movie.title.rendered}</p>
<p><strong>Release Year:</strong> {movie.acf.release_year}</p>
<p><strong>Rating:</strong> {movie.acf.rating}</p>
<div><strong>Description:</strong><div dangerouslySetInnerhtml={ {__html: movie.acf.description} } /></div>
</div>
});
return (
<div>
<h2>Star Wars Movies</h2>
{movies}
</div>
)
}
}
export default MoviesHub;
MoviePage.js
import React from 'react';
class MoviePage extends React.Component {
constructor() {
super();
this.state = {
movie: []
}
}
componentDidMount() {
console.log('MoviePage componentDidMount');
let dataURL = 'http://localhost:8888/SBP/website/wp-json/wp/v2/movies/'+this.props.match.params.number;
fetch(dataURL)
.then(results => {
return results.json();
})
.then(data => {
debugger;
this.setState({
movie: data
})
console.log("movie", this.state.movie);
})
}
render() {
let movie = this.state.movie;
return <div>
<img src={movie._embedded['wp:featuredmedia'][0].media_details.sizes.large.source_url} alt={movie.title.rendered} />
<p><strong>Title:</strong> {movie.title.rendered}</p>
<p><strong>Release Year:</strong> {movie.acf.release_year}</p>
<p><strong>Rating:</strong> {movie.acf.rating}</p>
<div><strong>Description:</strong><div dangerouslySetInnerHTML={ {__html: movie.acf.description} } /></div>
</div>
}
}
export default MoviePage;
作为参考,我正在从this tutorial建设,并试图将其提升到一个新的水平
任何帮助将不胜感激,并且任何关于如何改进我的代码以符合最佳实践的建议都会很棒。
谢谢大家。
我认为问题在于你实际上并没有将你的反应应用程序附加到DOM。在某个地方,您需要使用ReactDOM将您的应用程序附加到页面上的某个根元素。然后,您的组件将安装并呈现。
这对你来说可能是这样的:
ReactDOM.render(App, document.getElementById('my-root-element'))
看看the documentation了解更多信息。
编辑
我认为你可能会在导致这种情况的渲染上出现错误。如果在初始渲染时出现错误,则永远不会将其发送到componentDidMount。
如果你查看你的MoviePage
类,你在初始化时设置movie: []
的状态。你最终会获取一部电影,这可能是一个对象。但是在你完成获取数据之前,你将调用你的渲染函数,它试图访问该电影的数据,如:
movie._embedded['wp:featuredmedia'][0].media_details.sizes.large.source_url
两个快速提示:
- 使用与您希望州返回的类型相同的类型预填充您的州。因此,如果您希望电影成为一个对象,请将初始状态设为
movie: {}
。 - 在使用数据呈现元素之前,请确保已加载数据。有一个条件,您可以在其中呈现微调器或加载消息,直到数据返回。
示例渲染功能:
render() {
if (Object.keys(movie).length === 0) { // check if movie object is empty
return <div>Data not loaded</div>;
} else {
return (
... whatever you had
);
}
}
以上是关于React Child componentDidMount不在Route上触发的主要内容,如果未能解决你的问题,请参考以下文章
React Context - Context和Child render没有更新。
对象作为 React-Child 无效 > 使用数组代替异常
react native routerflux 遇到两个key相同的child