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

时间:2018-03-07 16:08:51

标签: reactjs react-router

我正在尝试使用React创建SPA。 我有index.jsApp.js, SidebarContentWrap.js, Sidebar.js, Content.js个组件。

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

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

根据我的理解,只要路由匹配,componentWillMount中的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;

2 个答案:

答案 0 :(得分:3)

@Transactional(readOnly = false) public int remove(int id) { return hibernateTemplate.getSessionFactory().getCurrentSession() .createQuery("DELETE FROM User qz WHERE u.id= :id") .setParameter("id", id).executeUpdate(); } 仅在首次呈现组件时调用一次。当您的路线发生变化时,您无法卸载该组件,这就是为什么public enum TypeUser { MEMBER, ADMIN; } 永远不会再被调用的原因。您想要的是使用componentWillMount代替。更改路径时,新的路由器道具将传递给组件。因此,您应该使用componentWillMount来对网址更改做出反应。

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

componentWillMount

答案 1 :(得分:1)

如果使用链接更改路径,则组件不会重新装入,而是重新渲染。您需要将提取逻辑添加到componentWillReceiveProps

class SidebarContentWrap extends Component {
  //...
  componentWillReceiveProps(nextProps) {
        //fetch
  }
}