我可能在这里遗漏了一些东西,使用 Link 更改 react-router 参数将导致props随新参数更改并触发更新周期。
您不能在更新周期中调度操作,但这是参数可用的唯一地方。当我的无状态组件中的 day 参数发生变化时,我需要获取新数据。
该组件有 2 个链接,前一天和后一天。前一天看起来像这样:
<Link to={"/sessions/" + prefDay}>{prefDay}</Link>
[更新]
这是迄今为止的解决方案:
Overview 组件只是一个接受 props 并返回 jsx 的函数,下面是检查日期是否设置的容器,如果不是,它将重定向。如果设置了日期,那么它将返回概览。
它还检查路由器日期参数是否更改,如果更改,则将 dispatchFetch 设置为 true。
这将导致渲染函数异步调度 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);