React Redux:动作创建者不调用reducer

Posted

技术标签:

【中文标题】React Redux:动作创建者不调用reducer【英文标题】:React Redux : Action creator not calling reducer 【发布时间】:2017-08-02 06:03:20 【问题描述】:

我的动作创建者没有调用我的减速器。任何帮助都感激不尽。

types.js

export const SELECTED_FOOD = 'selected_food';

index.js(动作创建者/动作)

import 
  SELECTED_FOOD
 from './types';

export function selectedFood(data) 
console.log('SELECTED_FOOD **********************',data);
  return(
    type: SELECTED_FOOD,
    payload: data
  );

console.log 在操作创建者中的输出

Object _id: "18240", description: "Croissants, apple", score: 0.75, fields: Object

selected_food_reducer.js

import 
SELECTED_FOOD

 from '../actions/types';

export default function(state = [], action) 
 switch(action.type) 
  case SELECTED_FOOD:
    console.log('Selected Food Reducer *************', state);
    return  action.payload ;


return state;

EDIT 组件调用调度失败。

我应该在我最初的帖子中添加这个,看来调用 dispatch 的方式有问题。 ESLint 在第 3 行标记了已定义但从未使用过的调度。

import React from 'react';
import  connect  from 'react-redux';
import  dispatch  from 'react-redux';
import  selectedFood  from '../actions/index';

class TableRow extends React.Component 
  render() 
    const 
      data
     = this.props;


    console.log('PROPS TableRow', this.props);

    const row = data.map((data) =>
    <tr onClick=() => selectedFood(data)>
      <td key=data.description>data.description</td>
      <td key=data.id>data.fields.nutrients[0].amountPer100G</td>
      <td key=data.id>data.fields.nutrients[1].amountPer100G</td>
      <td key=data.id>data.fields.nutrients[4].amountPer100G</td>
    </tr>
    );
    return (
      <tbody>row</tbody>
    );
  


const  mapStateToProps = (state) => 
  return 
    selectedFood: state.selectedFood
  



const mapDispatchToProps = (dispatch) => 
  console.log('IN mapDispatchToProps')
  return 
    onClick: (data) => 
      dispatch(selectedFood(data))
    
  


export default connect(mapStateToProps, mapDispatchToProp)(TableRow);

【问题讨论】:

你需要调度它而不是仅仅调用它 【参考方案1】:

Redux 中有一个经常被遗忘的规则,即当你更改 reducer 时,你需要重新启动 localhost 服务器。

你做对了——有很多方法可以将 Redux 构建到 React 中。如果您使用 connect()() 导入动作创建者,则不需要使用 mapDispatchToProps。

如果您没有看到任何拼写错误,只需重新启动您的本地主机服务器。 (我一般都是用npm,所以在终端中control+c out npm start,每次新增reducer的时候再运行npm start。)

【讨论】:

【参考方案2】:

动作创建者调用reducer。它就是它本身,仅此而已,它创建了一个动作 - 即具有动作类型和该动作有效负载的对象。

你需要dispatch一个action,强制redux调用reducer,这就是你使用action creator的地方,也就是:

import  Dispatch  from "redux";
import  selectedFood  from "./actions";
Dispatch(selectedFood(type:"hamburger"));

这应该调用 reducer,但大多数情况下你不会直接调用 Dispatch,而是在你的 mapDispatchToProps 方法中调用,用于将你的 react 组件连接到 redux 存储。

有很多示例如何使用react-redux 来使用上述地图功能,所以我建议阅读它,并阅读 redux 的工作原理。

====== 问题更新后编辑 =========

所以首先没有使用从 import 调度,ESLint 是正确的告诉它,你不需要那个 import,因为在:

const mapDispatchToProps = (dispatch) => 
  console.log('IN mapDispatchToProps')
  return 
    onClick: (data) => 
      dispatch(selectedFood(data))
    
  

您不会仅从参数中从 import 调用 dispatch,而是通过 connect 函数将其传递给您的 mapDispatchToProps

那么这是完全错误的:

<tr onClick=() => selectedFood(data)>

您导入了在点击表格行时调用的动作创建者,即动作定义由动作创建者创建,仅此而已。你的代码完全按照你写的那样做。

mapDispatchToProps 函数顾名思义 - 它将调度函数映射到组件的 props。

应该是这样的:

<tr onClick=() => this.props.onClick(data)>

这应该调度动作和工作。

但是我会强烈建议参加一些课程或阅读更多关于reactreduxreact-redux 的信息,因为您的代码示例和问题本身建议,您只是试图让某些东西工作,而没有基本了解它是如何工作的,甚至 javascript 是如何工作的。很抱歉那条评论,但这就是它的样子。

【讨论】:

谢谢 Alek,我最初并没有导入 dispatch,但是这样做之后,它仍然可以工作,并且 ESLint 将其标记为已声明但从未使用过。我认为 mapDispatchToProps 中有一些不正确的地方,但我没有看到它。 编辑了我的答案。 谢谢你,Alek,这是个好建议。昨晚我再次浏览并阅读了redux文档并发现了问题。它帮助清理了很多。我打算更新我的帖子。再次感谢您的帮助 =) 如果我的帖子对您​​有所帮助,请随时将其标记为答案 :-) @alekkowalczyk 的精彩解释【参考方案3】:

我认为您可能需要展示您是如何导入其他文件的。我对您分享的内容的观察:

1) 您需要从类型中导入SELECTED_FOOD

2) 你的return state 应该在 switch 语句的上下文中。

【讨论】:

以上是关于React Redux:动作创建者不调用reducer的主要内容,如果未能解决你的问题,请参考以下文章

Redux - reducer 与动作的关系

关于redux应用

Redux 动作/reducers 与直接设置状态

所有的 redux 动作都应该有相应的 reducer 吗?

React Native Redux:动作分派,返回结果

在组件内调用多个操作时 Redux Reducer 的行为