我正在使用React和Redux作为搜索应用程序 . 使用 react-router-dom
,我将 /search/:term?
路由到 Search
组件:
<Router>
<Switch>
<Route exact path="/search/:term?" component={Search} />
<Redirect to="/search" />
</Switch>
const Search = (props) => {
const { term } = props.match.params;
return (
<div>
<SearchForm term={term}/>
<SearchResults />
</div>
)
};
当用户在 SearchForm
组件中提交搜索时,如果给出了一个术语,我也会在构造函数中启动搜索,最初:
class SearchForm extends Component {
constructor(props) {
super(props);
const term = props.term ? props.term : '';
this.state = {
term: term,
}
if (term) {
this.props.submitSearch(term);
}
}
handleSubmit = (e) => {
e.preventDefault();
if (this.state.term) {
this.props.submitSearch(this.state.term);
}
}
render = () => {
<form
onSubmit={this.handleSubmit.bind(this)}>
...
</form>
}
}
我正在使用来自 react-router-dom
的 withRouter
,因此在提交搜索时会更新URL .
The problem happens when the user navigates Back in their browser. URL导航回来,道具更新(即 props.match.params.term
),但搜索不会重新提交 . 这是因为 submitSearch
动作仅在 SearchForm.constructor
(如果术语在URL中的初始加载时搜索)和 SearchForm.handleSubmit
中调度 .
当URL更改时,监听状态更改为 term
的最佳方法是什么,然后调度搜索操作?
2 回答
我会在
componentDidMount
中检索路由参数,因为您正在推送新路线并因此重新加载视图 .在你的SearchForm中,它看起来像这样 .
在您的SearchResult中:
一件好事就是保持SearchResult组件干燥 . 有几种方法可以实现这一点,这里有一个使用higher order components aka HOC:
然后,您将使用装饰器调用SearchResult组件 .
我目前的解决方案是,如果新道具与当前道具不匹配,则在
componentWillRecieveProps
生命周期方法中调度submitSearch
:然后,我不是在表单提交上调度操作,而是将新位置推送到
history
并执行调度componentWillReceiveProps
:这个解决方案感觉有点不对劲,但它确实有效 . (其他人似乎同意:Evil things you do with redux — dispatch in updating lifecycle methods)
这样做会违反React或Redux原则吗?我可以做得更好吗?