Redux Reducer更新值,但未反映在道具中

时间:2020-01-30 11:23:56

标签: javascript reactjs redux

当我使用ComponentDidMount()函数时,我在React Redux存储中设置了一些值。 Redux Dev Tools显示状态已更新。但是在props中,它没有改变。

我的reducer.js是

const inititalState = {
    slickColumns: null,
    slickData: null
}

const reducer = (state = inititalState, actions) => {
    switch(actions.type) {
        case actionsTypes.SET_SLICK_GRID_COLUMNS: {
            return {
              ...state,
              slickColumns: columns
            };
        }
        case actionsTypes.SET_SLICK_GRID_DATA: {

            return {
              ...state,
              slickData: [...mock_slick_data]
            };
        }
        default: {
            return state;
        }
    }
}

export default reducer;

action.js,

import * as actions from './actions';
export const setSlickGridColumns = () => {
    return {
        type:actions.SET_SLICK_GRID_COLUMNS
    }
}
export const setSlickGridData = () => {
    return {
        type: actions.SET_SLICK_GRID_DATA
    }
}

main.js,(将Redux映射为状态)

const mapStateToProps = state => {
  return {
    slickColumns: state.slickColumns,
    slickData: state.slickData
  };
};

const mapDispatchToProps = dispatch => {
  return {
    onSetSlickDataColumns: () => {
      dispatch(actionTypes.setSlickGridColumns());
    },
    onSetSlickData: () => {
      dispatch(actionTypes.setSlickGridData());
    }
  };
};
export default connect(mapStateToProps, mapDispatchToProps)(Dimensions()(Home));

在ComponentDidMount函数中,

this.props.onSetSlickDataColumns(); // able to see this method is running and the state is updated in Redux Dev Tools
this.props.onSetSlickData();
console.log(this.props.slickColumns); // getting null here. 
dv.setItems(this.props.slickData);

即使状态在商店中已更新,我仍然无法获取道具中的数据?为什么?有什么想法吗?

index.js,

import slickReducer from './store/reducers/SlickGrid';
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(
  slickReducer,
  composeEnhancers(applyMiddleware(thunk))
);
const app = (
  <Provider store={store}>
    <BrowserRouter>
      <App />
    </BrowserRouter>
    </Provider>

);
ReactDOM.render(app, document.getElementById("root"));

[Edit]:最初,我将initialState对象属性设置为'null; 在此处添加我的Redux屏幕截图, enter image description here

在此处添加其他一些日志。这可能有助于解决此问题。实际上,网格实例是通过ComponentDidMount()方法创建的。

  componentDidMount() {
    console.log("[componentDidmount]....");
    this.props.onSetSlickDataColumns();
    this.props.onSetSlickData();
    console.log(this.props);

    if (this.props.slickColumns.length !== 0) {
      const grid = (this.gridInstance = new Grid(
        this.grid,
        dv,
        this.props.slickColumns,
        options
      ));

     //  ------------------
     }
 }

当做网格对象时,它不应该有空的列和空的DataView。

我在各种生命周期方法(例如setSlickGridColumnssetSlickGridData中调用了constructorcomponentWillMount方法,并将道具的控制台日志放入了mapStateToProps,{{ 1}},constructorcomponentWillMountrender方法。从日志中,我得到的是

componentDidMount

从日志中,我了解的是,必须在[mapStateToProps] this.props.slickColumns: null [componentConstructor].... calling onSetSlickDataColumns() and onSetSlickData() methods here.. this.props.slickColumns: null [componentwillmount].... calling onSetSlickDataColumns() and onSetSlickData() methods here.. this.props.slickColumns: null [render] this.props.slickColumns: null [componentDidmount].... calling onSetSlickDataColumns() and onSetSlickData() methods here.. this.props.slickColumns: null [mapStateToProps] this.props.slickColumns: Array(300) // Here props values are set [render] this.props.slickColumns: Array(300) ()方法之前填充数据。但是,即使我在componentDidMountconstructor中调度了reducer函数,它也没有设置。希望此日志有助于解决此问题。

3 个答案:

答案 0 :(得分:3)

问题是您没有在减速器中设置新数据,您可以看到

const reducer = (state = inititalState, actions) => {
    switch(actions.type) {
        case actionsTypes.SET_SLICK_GRID_COLUMNS: {
            return {
              ...state,
              slickColumns : columns   // you have to pass your new data as payload from your function : actions.payload
            };
        }
        case actionsTypes.SET_SLICK_GRID_DATA: {

            return {
              ...state,
              slickData: [...mock_slick_data] // same here 
            };
        }
        default: {
            return state;
        }
    }
}

您可以在分派操作时传递数据

dispatch(actionTypes.setSlickGridColumns('Pass your data here '));

然后,您可以像

这样的参数获取数据
export const setSlickGridColumns = (data) => {
    return {
        type:actions.SET_SLICK_GRID_COLUMNS,
        payload : data // pass your data as payload 
    }
}  

现在您可以在 reducer 中使用数据,例如actions.payload

 .......

 case actionsTypes.SET_SLICK_GRID_COLUMNS: {
                return {
                  ...state,
                  slickColumns : action.payload 
                };
 ........

答案 1 :(得分:1)

尝试下面的代码->您需要像下面这样在mapDispatchToProps内部返回分派

const mapDispatchToProps = dispatch => {
  return {
    onSetSlickDataColumns: () => {
      return dispatch(actionTypes.setSlickGridColumns());
    },
    onSetSlickData: () => {
      return dispatch(actionTypes.setSlickGridData());
    }
  };
};

答案 2 :(得分:0)

实际上,您不会在componentDidMount生命周期挂钩中获得更新的道具,因为在挂载组件之后将调度函数。您将在rendercomponentWillReceiveProps(不推荐使用),getDerivedStateFromProps和其他一些生命周期挂钩中获得更新的道具。您可以在react official docs中了解有关在更新道具时调用哪些生命周期挂钩的更多信息。 然后,您将丢失mapDispatchToProps中的return语句,如另一个答案中所述。