首页 文章

从Redux容器调度操作而不扩展React.Component

提问于
浏览
1

我的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'虽然我_488992是一个常用术语 .

是否有一种从Pure Container发送操作的通用模式?我在想没有:

  • 期望表示组件通过将onLoad事件传递给它来担心这个逻辑

  • 使容器成为React.Component并通过componentDidMount触发

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

3 回答

  • 0

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

    • 将你的状态,动作创建者映射到组件道具

    • 检查 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

  • 1

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

    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来管理副作用,这个问题变得多余 .

  • 1

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

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

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

    然后,在您的组件中,您可以检查myData . 如果它不在那里,那么你通过发送

    this.props.whatYouCalledDispatch()
    

相关问题