【问题标题】:Redux reducers initializing same state keyRedux reducer 初始化相同的状态键
【发布时间】:2015-09-20 01:07:22
【问题描述】:

我在搞砸'simplest-redux-example' on github,我添加了第二个减少 state.count 的减速器。如果我在 switch case 语句中有递增和递减减速器,它工作正常。我想要执行的练习是将减速器拆分为尽可能多的模块化部分。此代码抛出一个错误,指出计数未定义。

import React from 'react';
import { createStore, combineReducers } from 'redux';
import { Provider, connect } from 'react-redux';

// React component
class Counter extends React.Component {
  render(){
    const { value, onIncreaseClick, onDecreaseClick } = this.props;
    return (
      <div>
        <span>{value}</span>
        <button onClick={onIncreaseClick}>Increase</button>
        <button onClick={onDecreaseClick}>Decrease</button>
      </div>
    );
  }
}

// Action:
const increaseAction = {type: 'increase'};
const decreaseAction = {type: 'decrease'};

// Reducer:
function counter(state, action) {
  let count = state.count;
  switch(action.type){
    case 'increase':
      return {count: count+1};
    default:
      return state;
  }
}
function decrementer(state, action) {
  let count = state.count;
  switch(action.type){
    case 'decrease':
      return {count: count -1};
    default:
      return state;
  }
}
const rootReducer = combineReducers({
  counter,
  decrementer
})

// Store:
let store = createStore(rootReducer, {count: 0});

// Map Redux state to component props
function mapStateToProps(state)  {
  console.log("mapStatetoProps heyyyy");
  return {
    value: state.count
  };
}

// Map Redux actions to component props
function mapDispatchToProps(dispatch) {
  console.log("mapDispatchtoProps heyyyy");
  return {
    onIncreaseClick: () => dispatch(increaseAction),
    onDecreaseClick: () => dispatch(decreaseAction)
  };
}

// Connected Component:
let App = connect(
  mapStateToProps,
  mapDispatchToProps
)(Counter);

React.render(
  <Provider store={store}>
    {() => <App />}
  </Provider>,
  document.getElementById('root')
);

【问题讨论】:

  • 它在哪一行说明了这一点?
  • 在计数器函数中的let count = state.count。
  • 你试过console.log(state)吗?
  • 是的...未定义

标签: javascript reactjs redux


【解决方案1】:

传递给combineReducers 的reducer 获得状态对象的不同片段

生成的 reducer 调用每个子 reducer,并将它们的结果收集到单个状态对象中。 状态对象的形状与传递的reducers 的键相匹配。

(强调我的)

所以,内部状态对象看起来像

{
  counter: result of passing `state.counter` into counter reducer
  decrementer: result of passing `state.decrementer` into decrementer reducer
}

这类似于在 Flux 应用程序中拥有单独的商店,其中每个商店都运行自己的全局应用状态“部分”。

由于您实际上希望这两个 reducer 在状态对象的 相同 部分上工作,因此您实际上想要更像 reduce-reducers 的东西,尽管您自己很容易实现 - 只需传递状态依次进入每个reducer,用每个reducer的新状态来减少初始状态。

其实就是这么简单,实现就几行:

export default function reduceReducers(...reducers) {
  return (previous, current) =>
    reducers.reduce(
      (p, r) => r(p, current),
      previous
    );
}

你的 rootReducer 会是

const rootReducer = reduceReducers(counter, decrementer);

【讨论】:

  • 谢谢! reduce-reducer 是一个很好的技巧。我最终能够看到我的状态实际上是state = {counter: {count:0}, decrementer: {count:0}}
【解决方案2】:

你离得太近了!问题是,当您使用 combineReducers 时,它实际上会拆分“状态”,以便您输入的减速器的状态是“状态”对象的属性。

因此,为了向它们提供默认参数,如下所示: let store = createStore(rootReducer, {counter: {count: 0}, decrementer: {count:0}});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-01-02
    • 1970-01-01
    • 1970-01-01
    • 2016-02-18
    • 2019-11-22
    • 2023-03-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多