【问题标题】:State does not change in my reducer when action is dispatched调度操作时,我的减速器中的状态不会改变
【发布时间】:2017-02-17 15:56:25
【问题描述】:

我无法在 reducer 中检索 state

MyComponent 看起来像这样

const MyComponent = ({name, features, onClick}) => {
  return (
        <div>
            Hello! {name}
            <Button onClick={() => { onClick(features); }}> Weight</Button>
        </div>
    );

const mapDispatchToProps = (dispatch: any) => {
  return {
    onClick: (features) => {
        dispatch(weightSort(features));
    }
  };
};
const mapStateToProps = (state: any, ownProps: any) => {
  console.log(state); //Displays the state
  return {
    name: "John Doe",
    features: ownProps.features,
  };
};

export const FeatureBlock = connect(mapStateToProps, mapDispatchToProps)(MyComponent);

我的 action 和 reducer 如下所示:

// Action Creator
export const  weightSort = (features) => {
console.log("inside the weight sort action creator!!!");
  return {
    type: "SET_WEIGHT_FILTER",
    filter: "DESC",
    features,
  };
};

// Reducer
export const weightFilter = (state = [], action) => {
  switch (action.type) {
    case "SET_WEIGHT_FILTER":
        console.log(state); // Gives me empty state
        console.log("++inside weight filter+++++", action); //Displays action
        return state;
    default:
        return state;
  }
};


export const FeatureBlock = connect(
  mapStateToProps,
  mapDispatchToProps,
)(MyComponent);

我在这里缺少什么?任何帮助将不胜感激!

【问题讨论】:

    标签: redux react-redux


    【解决方案1】:

    在你的 reducer 中,当你 console.log(state) 时,返回一个空数组是正确的,因为你没有做任何修改。

    // Reducer
       export const weightFilter = (state = [1,2,3], action) => {
         switch (action.type) {
           case "SET_WEIGHT_FILTER":
               console.log(state); // This will show [1,2,3] because [1,2,3] is the initial state.
               console.log("++inside weight filter+++++", action); //Displays action
               return state;
           default:
               return state;
         }
       };
    

    我猜你的减速器需要这样的东西:

    // Action Creator
    export const  weightSort = (name, features) => {
    console.log("inside the weight sort action creator!!!");
      return {
        type: "SET_WEIGHT_FILTER",
        name,
        features,
      };
    };
    // Reducer
      export const weightFilter = (
        state = {
          name: '',
          features: [],
        },
        action
      ) => {
         switch (action.type) {
           case "SET_WEIGHT_FILTER":
               return {...state, name: action.name, features: action.features}
           default:
               return state;
         }
       };
    

    然后在您的mapStateToProps 中,您将绘制出如下属性:

    const mapStateToProps = (state: any, ownProps: any) => {
      console.log(state); //Displays the state
      return {
        name: state.weightFilter.name,
        features: state.weightFilter.features,
      };
    };
    

    你的按钮会有一个 name 属性传递给函数,如下所示:

    <Button onClick={() => { onClick(name, features); }}> Weight</Button>
    

    如果您想对数据进行排序,可以在 reducer 或容器内进行。我更喜欢在容器中进行,并且喜欢使用 lodash sortBy 函数。它的工作原理是这样的:

    import { sortBy } from 'lodash' //be sure to npm install lodash if you use this utility
    ...
    ...
    function mapStateToProps(state) {
      return {
        name: state.weightFilter.name,
        features: sortBy(features, ['nameOfPropertyToSortBy'])
      };
    }
    

    这是关于 sortBy 的 lodash 文档:https://lodash.com/docs/4.17.4#sortBy

    希望有帮助!

    【讨论】:

    • 感谢您的回复。如果我必须根据按钮单击对功能进行排序,我会怎么做?(我想像你正确指出的那样在组件中包含排序)如果我想把它放在 mapDispatchToProps function mapDispatchToProps = ({ onFeaturesClick: orderFeatures @987654332 @ 你会怎么做?
    • 您将创建一个接收对象属性名称的动作调度,以便您可以将其传递给您的减速器。在您的减速器中,您可以使用从您的操作传递的属性来对减速器中的数据进行排序并返回一个新对象。另一种选择是在渲染数据的容器中创建一个状态属性,例如sortProperty,并将 onClick 处理程序绑定到在 sortProperty 上设置状态的按钮。然后在映射项目的表中,使用排序函数对项目进行排序。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-22
    • 2018-02-02
    相关资源
    最近更新 更多