【问题标题】:Redux - reducer not getting calledRedux - 减速器没有被调用
【发布时间】:2017-03-12 01:51:55
【问题描述】:

我正在努力学习 Redux。我遵循了在线教程并使用了他们的示例,并且效果很好。然后我制作了另一个小型测试应用程序,它运行良好。现在我正在尝试另一个小型测试应用程序,但我遇到了这个错误,不知道为什么。

该应用程序只是一个输入框和一个按钮,当您单击按钮时,它会将框中的所有内容添加到下面显示的列表中。

但是,reducer 不会更新状态。我查看了导致此问题的常见问题,但似乎在我的错误中找不到这些错误,我的减速器没有改变状态,我已经绑定了调度等等。也许我只是在某个地方拼错了一些东西(或者像这样的小而愚蠢的东西),但我就是无法让它工作。

所以我尝试对其进行更改,使其仅显示您在下面的框中键入的任何内容,但仍然无法正常工作。有人知道为什么减速器没有激活吗?

index.js(主要)

import 'babel-polyfill';
import React from 'react';
import ReactDOM from 'react-dom';
import {Provider} from 'react-redux';
import {createStore, applyMiddleware} from 'redux';
import thunk from 'redux-thunk';
import promise from 'redux-promise';
import createLogger from 'redux-logger';
import allReducers from './reducers';
import App from './components/App';

const logger = createLogger();
const store = createStore(
    allReducers,
    applyMiddleware(thunk, promise, logger)
);

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

App.js

import React from 'react';
import NameList from '../containers/name-list.js'
import Input from '../containers/input.js'

const App = () => (
  <div>
    <Input />
    <hr />
    <NameList />
  </div>
);

export default App;

index.js(动作)

export const addName = (name) => {
    return {
        type: 'NAME_ADDED',
        payload: name
    }
};

reducer-add-name.js

export default function (state = null, action) {
    switch (action.type) {
        case 'NAME_ADDED':
            return action.payload;
            break;
    }
    return state;
}

index.js(reducer 组合器)

import {combineReducers} from 'redux';
import AddNameReducer from './reducer-add-name';


const allReducers = combineReducers({
    nameList: AddNameReducer
});

export default allReducers

input.js

import React, {Component} from 'react';
import {bindActionCreators} from 'redux';
import {connect} from 'react-redux';
import {addName} from '../actions/index'

class Input extends Component {
  render() {
    return(
      <div>
        <input id='name-input' />
        <button id='add-name-button' onClick={() => addName(document.getElementById('name-input').value)}>Add name</button>
      </div>
    );
  }
}

function mapStateToProps(state) {
  return {
    nameList: state.nameList
  };
}

function matchDispatchToProps(dispatch) {
  return bindActionCreators({addName: addName}, dispatch);
}

export default connect(mapStateToProps, matchDispatchToProps)(Input);

name-list.js

import React, {Component} from 'react';
import {bindActionCreators} from 'redux';
import {connect} from 'react-redux';

class NameList extends Component {

  getNameList() {
    //This is where I'll loop through this.props.nameList and build the list of elements
    return this.props.nameList;
  }

  render() {
    return(
      <div>Current list : {this.getNameList()}</div>
    );
  }
}

function mapStateToProps(state) {
  return {
    nameList: state.nameList
  };
}

export default connect(mapStateToProps)(NameList);

感谢您的帮助!

【问题讨论】:

  • 检查控制台是否有任何错误。我也看不到你的 reducer 导出 AddNameReducer(在 index.js 中导入),但你可能只是错过了这篇文章而不是真正的代码。
  • 在任何时候都没有控制台错误。而AddNameReducer只是reducer-add-name.js文件,是单个导出函数。
  • input.js 中的 connect 函数将 dispatch 方法映射到 Input 组件的 props。那么当 Input 组件的渲染函数调用 addName 时,它​​会期望将 this 作为 prop 引用吗? (所以试试 this.props.addName)

标签: reactjs redux state


【解决方案1】:

我认为您的操作尚未发送。

在您的 input.js 中 在按钮标签上,更改

onClick={() => addName(document.getElementById('name-input').value)}

onClick={() => this.props.addName(document.getElementById('name-input').value)}

动作应该通过 mapDispatchToProps 传递,'bindActionCreators(actions, dispatch)' 将用'dispatch' 包装你的动作,并通过道具'addName' 传递你的组件。 (在您的 mapDispatchToProps 中定义)

一个单独的动作就像一颗子弹(只是返回对象)你需要一些东西来发射它(调度)

你的情况

import {addName} from '../actions/index' <--- a bullet

已被声明,并且您的 onClick,如果不分派,它只会返回一个单纯的对象,而不是将其分派给 reducer。

addName() // <--- Just a bullet

但是

this.props.addName() // <--- bullet with a gun

来自 mapDispatchToProps / bindActionCreators...它有 dispatch() 包裹,这是我们将使用的。

【讨论】:

  • 谢谢你。我正在使用对象解构并忘记将操作添加到解构中
【解决方案2】:

您应该将现有状态与 reducer-add-name.js 中的新操作负载结合起来,而不是仅仅返回负载,即

return Object.assign({}, state, {
    todos: [
      ...state,
      {
        action.payload
      }
    ]
  })    

【讨论】:

    【解决方案3】:

    不是 OP 的问题,而是对于刚刚在 Google 上搜索“reducer not getting called”的人,请确保您致电您的操作创建者:

    dispatch(action())

    不是

    dispatch(action)

    您必须传入动作,而不是动作创建者。在 Redux Toolkit 中使用 useSelect 时,我通常在 arg 中没有括号,所以我忘记将父母放在对 dispatch 的调用中。

    【讨论】:

      【解决方案4】:

      今天发生在我身上。

      我在使用类方法时忘记将我的新动作添加到我在 React 中的解构道具中

      const { newAction } = this.props
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-01-11
        • 2018-04-15
        • 2017-09-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-02-02
        相关资源
        最近更新 更多