<Route> 中的组件未更新

A component in <Route> is not updating

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

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 相对应的页面(重新加载页面后,导航到其他 URLs* 之前的页面)。我真的不明白为什么它不更新,虽然我也认为我可能只是犯了一个非常简单的错误......
ᵃˡˢᵒᶦᵘˢᶦⁿᵍʳᵉᵃᶜᵗᵗʰᵃⁿᵃᵐᵒⁿᵗʰˢᵒᵈᵒⁿᵈᵒⁿᵈᵒⁿᵇˡᵃᵐᵉ

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






* 请注意,这不一定是根 URL,如果页面已加载,例如 /contacts<Page /> 将始终留在 那里

我不知道您是否忘记将 path 属性添加到您的 Route 但此答案假设您 did.检查 Route.

发生这种情况是因为 react-router 正在渲染同一个组件并更改 props 而您的组件没有处理它。这也意味着 react 不会重新挂载您的组件,因此即使 URL 发生变化,您也看不到显示的变化。

你有两种方法来解决这个问题。

  1. 轮询 this.props.location.pathnamecomponentDidUpdate 中的更改,并在 prop 更改时发出网络请求。 See Docs.
  2. 使用 react-router-dom 的 render props 方法到 return 一个带键的组件。 Render props route

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

A change in key forces react to re-mount the component which calls all the lifecycle methods from scratch and so can be used to remount the component in case of URL change.

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

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

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