我可能在这里遗漏了一些东西,使用Link更改react-router参数会导致道具随新参数更改并触发更新周期。
您无法在更新周期中调度操作,但这是参数可用的唯一位置。当我的无状态组件中的day参数发生变化时,我需要获取新数据。
该组件有2个链接,上一天和下一天。前一天看起来像这样:
<Link to={"/sessions/" + prefDay}>{prefDay}</Link>
[UPDATE]
到目前为止,这是解决方案:
Overview组件只是一个带有props并返回jsx的函数,以下是检查日期是否设置的容器,如果不是它将重定向。如果设置了日期,那么它将返回概述。
它还检查路由器天参数是否发生了变化,如果是,则将dispatchFetch设置为true。
这将导致render函数异步调度getData操作。
不确定是否还有其他方法可以做到这一点,我更愿意从路由器收听事件并从那里调度事件,但没有(工作)方式来收听路由器。
import { connect } from 'react-redux';
import React, { Component } from 'react';
import Overview from '../components/Overview';
import { getData } from '../actions';
import { selectOverview } from "../selectors";
import { Redirect } from "react-router-dom";
const defaultDate = "2018-01-02";
const mapStateToProps = (lastProps => (state, ownProps) => {
var dispatchFetch = false;
if (lastProps.match.params.day !== ownProps.match.params.day) {
lastProps.match.params.day = ownProps.match.params.day;
dispatchFetch = true;
}
return {
...selectOverview(state),
routeDay: ownProps.match.params.day,
dispatchFetch
}
})({ match: { params: {} } });
const mapDispatchToProps = {
getData
};
class RedirectWithDefault extends Component {
render() {
//I would try to listen to route change and then dispatch getData when
// routeDay changes but none of the methods worked
// https://github.com/ReactTraining/react-router/issues/3554
// onChange in FlexkidsApp.js never gets called and would probably
// result in the same problem of dispatching an event in update cycle
// browserHistory does not exist in react-router-dom
// this.props.history.listen didn't do anything when trying it in the constructor
//So how does one dispatch an event when props change in stateless components?
// can try to dispatch previous and next day instead of using Link component
// but that would not update the url in the location bar
if (this.props.dispatchFetch) {
Promise.resolve().then(() => this.props.getData(this.props.routeDay));
}
return (this.props.routeDay)//check if url has a date (mapStateToProps would set this)
? Overview(this.props)
: <Redirect//no date, redirect
to={{
pathname: "/list/" + defaultDate
}}
/>
}
}
export default connect(mapStateToProps, mapDispatchToProps)(RedirectWithDefault);
答案 0 :(得分:1)
最初我希望您的路由器像,
<Route path="/sessions/:prefDay" component={MyComponent}/>
您必须在getDerivedStateFromProps(),
中执行此操作static getDerivedStateFromProps(nextProps, prevState) {
if (prevState.prefDay !== nextProps.match.params.prefDay) {
return {
prefDay: nextProps.match.params.prefDay,
};
}
// Return null to indicate no change to state.
return null;
}
答案 1 :(得分:1)
您是否尝试过componentWillReceiveProps?
componentWillReceiveProps(props){
if(this.props.data != props.data && this.props.state.routeDay){
this.props.getData(props.state.routeDay);
}
}
答案 2 :(得分:0)
要在路由器中为路由添加参数,请执行此操作
<Route
path="/sessions/:prefDay"
....
/>
这意味着现在&#34; / sessions /&#34;溃败有一个名为&#34; prefDay&#34; 示例/会话/:prefDay
现在在Link组件中需要添加此参数
<Link to={"/sessions/" + prefDay}>{prefDay}</Link>
您可以像这样从
this.props.match.params.prefDay
答案 3 :(得分:0)
在RedirectWithDefaults中,它是无状态组件的容器,我添加了componentDidMount(不是更新周期方法):
const historyListener = (lastDay => (props,currentDay) => {
if(lastDay !== currentDay){
lastDay = currentDay;
if(!isNaN(new Date(currentDay))){
console.log("getting:",currentDay);
props.getData(currentDay);
}
}
})(undefined);
class RedirectWithDefault extends Component {
componentDidMount(history) {
this.props.getData(this.props.routeDay || defaultDate);
this.unListen = this.props.history.listen((location) => {
historyListener(
this.props,
location.pathname.split('/').slice(-1)[0]
);
});
}
componentWillUnmount(){
this.unListen();
}
从渲染功能中删除了代码。现在当它安装它时,它将调度操作来加载数据,当路由发生变化时,它将再次发送它,但不会在更新周期中发送。