<route>中的组件未更新

时间:2018-09-10 18:35:29

标签: reactjs react-router url-routing

最近,我一直在开发一个React应用,该应用从API提取数据和页面。因此,我没有创建<Index /><ContactUs /><AboutUs />等组件,而是在页面中间放置了一个<Page />组件。这是组件类,有点简化“”。

class Page extends Component {
    state = {
        content: ''
    }

    componentDidMount () {
        console.log(this.props)
        const component = this;
        fetch(`http://localhost:3001/pages/${this.props.location.pathname}`)
            .then((data) => {
                return data.json();
            }).then((response) => {
                component.setState({ content: response.content });
            })
            .catch((err) => {
                console.error(`An error was thrown! Error message: ${err}`);
            });
    }

    render () {
        return (
            <JsxParser
                components={ {
                    Button,
                    Typography
                } }

                jsx={ this.state.content }
            />
        )
    }
}

Page.propTypes = {
    location: PropTypes.object.isRequired
}

export default Router.withRouter(Page);

但是,如果我添加<Router.Route component={ Page } />,然后通过<Link>this.props.history.push() / replace()更改当前位置,则组件不会更新,并始终显示与原始URL对应的页面(重新加载页面之后,导航至其他URL *之前的页面)。我真的不明白为什么它没有更新,尽管我也认为我可能只是在犯一个非常简单的错误...
ᵃˡˢᵒˢᵗᵃʳᵗᵉᵈᵈᵒⁿᵈᵒⁿᵈᵒⁿs s s

编辑:
我试图将DidComponentUpdate方法添加到Page组件中;但是,尽管每次URL更改时组件确实都会更改道具,但是有关位置的所有道具(例如this.props.location.pathname)都保持不变。






*请注意,这不一定是根URL,例如,如果页面加载到/contacts上,则<Page />将始终存在

2 个答案:

答案 0 :(得分:0)

我不知道您是否忘记将路径道具添加到Route中,但是此答案假定您已完成。选中Route.

之所以发生这种情况,是因为反应路由器正在渲染具有相同道具的同一个组件,而您的组件却不在乎。这也意味着反应不会重新安装组件,因此即使URL发生变化,您也看不到显示的变化。

您有两种解决方法。

  1. 轮询this.props.location.pathnamecomponentDidUpdate的更改,并在更改道具后发出网络请求。 See Docs.
  2. 使用 react-router-dom 的render props方法返回带有键的组件。 Render props route

    <Route path="/:page" render={props => (
        <Page key={props.location.pathname} {...props} />
    )}/>
    
  

键更改反应以重新安装组件,该组件从头开始调用所有生命周期方法,因此可以用于在URL发生更改的情况下重新安装组件。

答案 1 :(得分:0)

尽管我没有设法直接更新该组件,但是我仍然设法通过将其包装到一个内联功能组件中来再次触发componentDidMount(),这是我实际渲染的。我用了这段代码

<Router.Route path='/*' component={ function ({ match }) {
    return <Page path={ match.url } />
} } />

显然,它比我想象的要简单...