开发者问题收集

react-redux dispatch undefined

2020-08-22
1335

在我的 App.js 中:

const initialAppState = {
  nums: {},
};
const reducer = (state = initialAppState, action) => {
  if (
    action.a === undefined ||
    action.b === undefined ||
    action.c === undefined
  ) {
    return state;
  }
  if (state.nums[action.a][action.b] === undefined) {
    state.nums[action.a][action.b] = {};
  }
  return {
    nums: (state.nums[action.a][action.b] =
      action.c),
  };
};

const store = createStore(reducer);

然后将其与 Provider 一起传递。 当我在 Test.js 中尝试更改值时,它给出了错误:

const mapStateToProps = (state) => {
  return {
    nums: state.nums,
  };
};

function mapDispatchToProps(dispatch) {
  return {
    add: (a, b, c) =>
      dispatch({a: a, b: b, c: c}),
  };
}
export default connect(mapStateToProps, mapDispatchToProps())(Test);

并且测试功能组件如下所示:

function Test({nums, dispatch})
...
function add(data, count) {
    dispatch.add('1','2','3');
  }

它给出了错误提示: TypeError:未定义不是对象(评估“dispatch.add”)

它不应该将 dispatch 识别为测试的参数,而 add 是该功能组件的另一个函数吗?

2个回答

这不是 dispatch.add() 而是 props.add()

// add comes in as a prop. that’s why it’s called map dispatch to props.
function Test({nums, add: doAdd})
...
function add(data, count) {
    doAdd('1','2','3');
}
ray
2020-08-23

我建议您整理代码。尝试将操作和减速器移至单独的文件,如actions.js、reducers.js。

减速器需要一些修复:

  • 在最后一个返回的减速器示例中,您尝试 改变状态
  • 此外,正如您在第二个 if 中看到的那样,没有 return

动作和减速器分离的提议

在您的 App.js 中,您将创建Store:

//App.js
import { reducer } from "./reducers"

const store = createStore(reducer);
<Provider store={ store }>
 ...
</Provider>

现在让我们做 actions.js 文件:

//actions.js
export const ADD_ACTION='ADD_ACTION' // action type

export function addAction(data) {
 return { type: ADD_ACTION, data }
}

在减速器中,您将从 App.js 中移动部分代码。我建议您在 Reducer 中使用 switch ,如下所示:

//reducers.js
import { ADD_ACTION } from "./actions";

const initialAppState = {
  nums: {},
};

export const reducer = (state = initialAppState, action) => {
  switch(action.type) {
    case ADD_ACTION:
      return Object.assign({}, state, { nums: action.data });
    default:
      return state
   }
};

如您所见,其中一个 ADD_ACTION 返回了具有更新的 nums 值的新对象。这是因为 Redux 的基本规则之一是 “不改变状态”

现在,让我们在 Test.js 中尝试我们的操作。首先从 actions.js 导入 addAction 。然后使用 addAction 作为参数调用 dispatch

//Test.js functional component version
import { addAction } from "./actions";

function Test({dispatch}) {
  ...
  function add(data, count) {
    dispatch(addAction(data));
  }
}

export default connect(null, null)(Test);

组件从 connect 接收 dispatch 。 Connect 具有 (null, null),因为在这种情况下我们不使用 mapStateToProps,也不使用 mapDispatchToProps。

额外提示 :对于类组件,您将以稍微不同的方式使用操作。

//Test.js Class component version
import React from 'react';
import { addAction } from "./actions";
import { connect } from 'react-redux';

class TestClass extends React.Component {
  render() {
    return(
      <button onClick={() => this.props.addAction(2)}>Action</button>
    )
  }
}

const mapDispatchToProps = ({
 addAction
});

export default connect(null, mapDispatchToProps)(TestClass);

在类组件示例中,当 onClick 事件触发时,您将使用值 2 调用操作。

工作沙盒示例: react-redux 示例

Aga
2020-08-22