首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当路由匹配时,Reactjs组件不调用componentWillMount方法

当路由匹配时,Reactjs组件不调用componentWillMount方法
EN

Stack Overflow用户
提问于 2018-03-07 16:08:51
回答 2查看 1.3K关注 0票数 2

我试图创建一个SPA使用的反应。我有一个index.jsApp.js, SidebarContentWrap.js, Sidebar.js, Content.js组件。

index.jsBrowserRouter,并调用App.js组件。

App.jscomponentWillMount方法中从API中获取数据,然后呈现一个动态路由<Route path={/播放列表/:slug} component={SidebarContentWrap}/>

根据我的理解,无论何时路由匹配,都将调用SidebarContentWrap中的SidebarContentWrap,我将在其中获取数据,然后呈现该数据。但这种事不会发生。

这是我的一些代码。

代码语言:javascript
复制
/*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;

代码语言:javascript
复制
/*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;
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-03-07 16:20:08

componentWillMount只在组件第一次呈现时调用一次。当您的路由更改时,您不会卸载该组件,这就是为什么componentWillMount不再被调用的原因。您想要的是使用componentWillReceiveProps代替。当您更改路由时,新的路由器道具将被传递给组件。因此,您应该使用componentWillReceiveProps来对url更改作出反应。

您仍然希望在第一次呈现组件时在componentWillMount中获取,但是在此之后,抓取应该在componentWillReceiveProps中进行。

代码语言:javascript
复制
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;
票数 4
EN

Stack Overflow用户

发布于 2018-03-07 16:20:27

如果使用Link更改路由,则组件不会重新挂载,而是重新呈现。您需要将获取逻辑添加到componentWillReceiveProps

代码语言:javascript
复制
class SidebarContentWrap extends Component {
  //...
  componentWillReceiveProps(nextProps) {
        //fetch
  }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49156448

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档