<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 发生变化,您也看不到显示的变化。
你有两种方法来解决这个问题。
- 轮询
this.props.location.pathname
在 componentDidUpdate
中的更改,并在 prop 更改时发出网络请求。 See Docs.
使用 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 } />
} } />
显然,它比我想象的要简单...
最近,我一直在开发一个从 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 发生变化,您也看不到显示的变化。
你有两种方法来解决这个问题。
- 轮询
this.props.location.pathname
在componentDidUpdate
中的更改,并在 prop 更改时发出网络请求。 See Docs. 使用 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 } />
} } />
显然,它比我想象的要简单...