从 Reducer 到容器的 Redux 数据流

Redux Dataflow from Reducer to Container

由于我是 redux 的新手,这里有一个关于 redux 中数据流的关键问题

据我了解,我创建了一个组件作为 CountN:

import React from 'react'

import styles from '../../features/counter/Counter.module.css'


const CountN = (props) => {
     
    const {countValue,actions} = props;
 
    
   

     return (
    
      <div>
           <div className={styles.row}>
                <button
                  className={styles.button}
                  aria-label="Increment value"
                  onClick={actions.increment}  
                >
                +
                </button>
                
                <span className={styles.value}>{ countValue }</span>
                
                <button
                  className={styles.button}
                  aria-label="Decrement value"
                  onClick={actions.decrement}
                >
                 -   
                </button>
           </div>
     </div>

          )

     }
        

export default CountN

然后我用容器传数据给CountN

以下容器:

import React from 'react';
import CountN from "../../components/countN"

import { connect } from 'react-redux'
import * as CountActions from '../../actions'
import { bindActionCreators } from 'redux';

const mapStateToProps = (state) =>({
       countValue: state.value
})

const mapDispatchToProps = (dispatch) =>({
       actions: bindActionCreators(CountActions,dispatch)
})


export default connect(
     mapStateToProps,
     mapDispatchToProps
)(CountN)

为了管理状态,我创建了 Reducer 来设置状态:

减速机如下:

import * as types  from '../constants/CountTypes';

const initialState = [{
    value: 0,
    payload: 0,

}]

 const counter = (state=initialState,action)=> {
    switch (action.type){
        case types.Increment:
            return [{
                value: state.value + 1,
                payload: 0,
            }]
        case types.Decrement:
            return [
                ...state,
                {
                    value: state.value - 1
                }
          
            ]
        case types.IncrementByAmount:
            return [{
                value: state.value + action.payload ,
                payload: action.payload
            }     
            ]
        default:
            return state
    
    }
};

export default counter;

另外,我用“CreateStore(reducer)”创建了一个存储来存储数据,

现在问题是我得到一个错误:

类型错误:无法读取未定义的 属性 'increment'

据我了解,状态未定义,

哪位高手能帮我看看哪里错了,为什么数据没有通过“props”传递给Container???

非常感谢

你的代码应该可以工作,但我确实对状态做了一些更改,你将它定义为一个数组,但我没有看到为什么所以我将它更改为一个对象。您的 mapStateToProps 不认为状态是一个数组,所以这可能是一个错误。请参阅下面我进行更改的代码中的注释。

const { Provider, connect } = ReactRedux;
const {
  createStore,
  applyMiddleware,
  compose,
  bindActionCreators,
} = Redux;

//I changed initialState to an object instead of an array
const initialState = {
  value: 0,
  payload: 0,
};
//action types
const types = {
  Increment: 'Increment',
  Decrement: 'Decrement',
  IncrementByAmount: 'IncrementByAmount',
};
//action creators
const CountActions = {
  increment: () => ({ type: types.Increment }),
  decrement: () => ({ type: types.Decrement }),
};
const reducer = (state = initialState, action) => {
  switch (action.type) {
    case types.Increment:
      //changed to object
      return {
        value: state.value + 1,
        payload: 0,
      };
    case types.Decrement:
      //changed to object
      return {
        ...state,
        value: state.value - 1,
      };
    case types.IncrementByAmount:
      //changed to object
      return {
        value: state.value + action.payload,
        payload: action.payload,
      };
    default:
      return state;
  }
};
//creating store with redux dev tools
const composeEnhancers =
  window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(
  reducer,
  initialState,
  composeEnhancers(
    applyMiddleware(() => (next) => (action) =>
      next(action)
    )
  )
);
const CountN = (props) => {
  const { countValue, actions } = props;
  return (
    <div>
      <div>
        <button
          aria-label="Increment value"
          onClick={actions.increment}
        >
          +
        </button>
        <span>{countValue}</span>
        <button
          aria-label="Decrement value"
          onClick={actions.decrement}
        >
          -
        </button>
      </div>
    </div>
  );
};
const mapStateToProps = (state) => ({
  countValue: state.value,
});

const mapDispatchToProps = (dispatch) => ({
  actions: bindActionCreators(CountActions, dispatch),
});

const App = connect(
  mapStateToProps,
  mapDispatchToProps
)(CountN);

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/4.0.5/redux.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-redux/7.2.0/react-redux.min.js"></script>
<div id="root"></div>