我试图创建一个SPA使用的反应。我有一个index.js和App.js, SidebarContentWrap.js, Sidebar.js, Content.js组件。
index.js有BrowserRouter,并调用App.js组件。
App.js在componentWillMount方法中从API中获取数据,然后呈现一个动态路由<Route path={/播放列表/:slug} component={SidebarContentWrap}/>
根据我的理解,无论何时路由匹配,都将调用SidebarContentWrap中的SidebarContentWrap,我将在其中获取数据,然后呈现该数据。但这种事不会发生。
这是我的一些代码。
/*App.js*/
class App extends Component {
constructor(props){
super(props);
this.state = {
playLists: [],
dataRoute: `${Config.apiUrl}playlists?per_page=3`
}
}
componentWillMount(){
fetch(this.state.dataRoute)
.then(res => res.json())
.then(playlists => this.setState((prevState, props) => {
return { playLists : playlists.map( playlist => {
return { name: playlist.name, slug: playlist.slug}
}
)};
}));
}
render() {
return (
<div className="App">
<Header />
<switch>
{/*<Route path={`/playlist/:slug`} render={({match})=><SidebarContentWrap match={match} playLists={this.state.playLists}/>}/>*/}
<Route path={`/playlist/:slug`} component={SidebarContentWrap}/>
</switch>
<Footer />
</div>
);
}
}
export default App;和
/*SidebarContentWrap.js*/
class SidebarContentWrap extends Component {
constructor(props){
super(props);
}
componentWillMount(){
//FETCH DATA HERE EVERY TIME WHEN URL IS CHANGED
}
render() {
return (
<div className="sidebar-content-wrap">
<div className="wrap clearfix">
<main className="App-content">
{/*<Route path={`/playlist/:slug`} render={()=><Content/>}/>*/}
<Content />
</main>
<aside className="App-sidebar">
<div className="tabs">
{/*{this.props.playLists.map((playlist) =>*/}
{/*<NavLink key={playlist.slug} to={`/playlist/${playlist.slug}`}>{playlist.name}</NavLink>*/}
{/*)}*/}
<NavLink key="playlist-1" to="/playlist/playlist-1">Playlist 1</NavLink>
<NavLink key="playlist-2" to="/playlist/playlist-2">Playlist 2</NavLink>
<NavLink key="playlist-3" to="/playlist/playlist-3">Playlist 3</NavLink>
</div>
<div className="tabs-content">
{this.props.match.params.slug}
{/*<Route path={`/playlist/:slug`} render={()=><Sidebar/>}/>*/}
<Sidebar />
</div>
</aside>
</div>
</div>
);
}
}
export default SidebarContentWrap;发布于 2018-03-07 16:20:08
componentWillMount只在组件第一次呈现时调用一次。当您的路由更改时,您不会卸载该组件,这就是为什么componentWillMount不再被调用的原因。您想要的是使用componentWillReceiveProps代替。当您更改路由时,新的路由器道具将被传递给组件。因此,您应该使用componentWillReceiveProps来对url更改作出反应。
您仍然希望在第一次呈现组件时在componentWillMount中获取,但是在此之后,抓取应该在componentWillReceiveProps中进行。
class SidebarContentWrap extends Component {
constructor(props){
super(props);
}
componentWillMount(){
this.fetchData(this.props);
}
componentWillReceiveProps(nextProps){
this.fetchData(nextProps);
}
fetchData(props) {
//FETCH DATA HERE EVERY TIME WHEN URL IS CHANGED
}
render() {
return (
<div className="sidebar-content-wrap">
<div className="wrap clearfix">
<main className="App-content">
{/*<Route path={`/playlist/:slug`} render={()=><Content/>}/>*/}
<Content />
</main>
<aside className="App-sidebar">
<div className="tabs">
{/*{this.props.playLists.map((playlist) =>*/}
{/*<NavLink key={playlist.slug} to={`/playlist/${playlist.slug}`}>{playlist.name}</NavLink>*/}
{/*)}*/}
<NavLink key="playlist-1" to="/playlist/playlist-1">Playlist 1</NavLink>
<NavLink key="playlist-2" to="/playlist/playlist-2">Playlist 2</NavLink>
<NavLink key="playlist-3" to="/playlist/playlist-3">Playlist 3</NavLink>
</div>
<div className="tabs-content">
{this.props.match.params.slug}
{/*<Route path={`/playlist/:slug`} render={()=><Sidebar/>}/>*/}
<Sidebar />
</div>
</aside>
</div>
</div>
);
}
}
export default SidebarContentWrap;发布于 2018-03-07 16:20:27
如果使用Link更改路由,则组件不会重新挂载,而是重新呈现。您需要将获取逻辑添加到componentWillReceiveProps中
class SidebarContentWrap extends Component {
//...
componentWillReceiveProps(nextProps) {
//fetch
}
}https://stackoverflow.com/questions/49156448
复制相似问题