在不扩展React.Component的情况下从Redux容器调度操作

时间:2017-08-16 14:05:19

标签: reactjs redux containers react-redux

我的React和Redux应用程序中有一个容器组件:

import { connect } from 'react-redux'

import MyComponent from '../components/mycomponent'

const mapStateToProps = state => ({
  myData: state.myData[state.activeDataId]
})

export default connect(mapStateToProps)(MyComponent)

如果state.myData[state.activeDataId]不存在,那么我想向fetchMyDatafetchMyDataIfNeeded发送操作。

请注意,目前,我的容器不包含任何JSX,它只是将道具转发给演示组件。我有seen this being called a 'Pure Container'虽然我不确定这是否是一个常用术语。

是否有从Pure Container调度操作的常见模式?我在想没有:

  • 希望表示组件通过向其传递onLoad事件来担心此逻辑
  • 使容器成为React.Component并通过componentDidMount
  • 触发

从mapStateToProps,mapDispatchToProps或mergeProps调度操作是不是一个坏主意?

3 个答案:

答案 0 :(得分:1)

如其他地方所述,在容器中执行此操作是一个坏主意。

不要在容器中担心这一点,而是在组件中有条件地获取数据。我知道你提到不想扩展react.component,但是你应该考虑将这个组件作为一个类来获取组件生命周期钩子中的数据。

如另一个答案所详述,connect接受mapDispatchToProps的第二个参数。在那里传递fetchData调度程序(如何执行此操作的示例here。)

然后,在您的组件中,您可以检查myData。如果它不存在,那么你通过

发送
this.props.whatYouCalledDispatch()

答案 1 :(得分:1)

是的,在容器中发送任何操作是个坏主意。 在您的情况下,最好的方法是:

  • 将您的州,行动创建者映射到组件道具
  • 检查componentDidMount(或componentDidUpdate)和fetchDataYouNeed中的道具,然后更新组件

您的容器应该是:

import { connect } from 'react-redux';
import {fetchDataYouNeed} from './actions
import MyComponent from '../components/mycomponent';

    const mapStateToProps = state => ({
      myData: state.myData[state.activeDataId]
    });

    const mapDispatchToProps = (dispatch) => {
      return {
        fetchDataYouNeed: ()=>{
          dispatch(fetchDataYouNeed());
        }
      };
    };

    export default connect(mapStateToProps, mapDispatchToProps)(MyComponent);

您的组件

class YourComponent extends Component{ 

  componentDidMount(){
    let {myData, activeDataId} = this.props;
    if(myData && !myData[activeDataId]){
      this.props.fetchDataYouNeed();
    }
  }

  render(){
    ....
  }
}

在此处了解详情https://facebook.github.io/react/docs/react-component.html#componentdidmount

答案 2 :(得分:0)

这似乎有效,但我不确定它是否有任何意想不到的影响:

import { connect } from 'react-redux'

import MyComponent from '../components/mycomponent'
import { fetchMyData } from '../actions/mydata'

const mapStateToProps = state => ({
  dataId: state.activeDataId,
  myData: state.myData[state.activeDataId]
})

const mapDispatchToProps = { fetchMyData }

const mergeProps = (stateProps, dispatchProps) => {
  if (!stateProps.myData) {
    dispatchProps.fetchMyData(stateProps.dataId)
  }
  return stateProps
}
export default connect(mapStateToProps, mapDispatchToProps, mergeProps)(MyComponent)

或者brianzinn suggested使用Redux Saga来管理副作用,这个问题就变得多余了。