web-dev-qa-db-ja.com

React Redux:アクション作成者がリデューサーを呼び出さない

アクションクリエーターがリデューサーを呼び出していません。どんな助けでも大歓迎です。

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コンポーネントがディスパッチの呼び出しに失敗しました。

私はこれを私の最初の投稿に追加するべきでした、ディスパッチの呼び出し方法に何か問題があるようです。 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);
9
kennedy

アクション作成者しないレデューサーを呼び出します。それはそれが何であるか、それ以上ではなく、アクションを作成します-つまり、アクションタイプとそのアクションのペイロードを持つオブジェクトです。

Reduxにリデューサーを強制的に呼び出すには、アクションをdispatchする必要があります。これが、アクションクリエーターを使用する場所です。

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

これはレデューサーを呼び出す必要がありますが、ほとんどの場合、Dispatchを直接呼び出すのではなく、reactコンポーネントをreduxストアに接続するために使用されるmapDispatchToPropsメソッドで呼び出します。

上記のマップ機能を使用するためのreact-reduxの使用方法のサンプルはたくさんあるので、これを読んでreduxの仕組みを読むことをお勧めします。

======質問の更新後の編集=========

したがって、最初にインポートからのディスパッチは使用されず、ESLintはそれを正しく伝えているため、次のようにインポートする必要はありません。

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

dispatchimportから呼び出すのは引数からではなく、mapDispatchToProps関数によってconnectに渡されます。

次に、これは明らかに間違っています:

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

テーブル行のクリックで呼び出されるアクション作成者をインポートしました。つまり、アクション作成者によってアクション定義が作成され、それだけです。あなたのコードはあなたが書いたものと全く同じです。

mapDispatchToProps関数は、名前が示すとおりに機能します。ディスパッチ関数をコンポーネントの小道具にマップします。

だからそれはする必要があります:

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

アクションとディスパッチをディスパッチする必要があります。

ただし思います強く提案コースを受講するか、reactreduxおよびreact-reduxの詳細を読むサンプルと質問自体は、それがどのように機能するか、さらにはJavaScriptがどのように機能するかという基本的な理解なしに、何かを機能させようとしているだけであることを示唆しています。そのコメントは申し訳ありませんが、それはそれがどのように見えるかです。

8
alek kowalczyk

他のファイルをインポートする方法を示す必要があるかもしれません。あなたが共有したものからの私の観察:

1)インポートする必要がありますSELECTED_FOOD型から。

2)あなたのreturn stateは、switchステートメントのコンテキスト内にある必要があります。

0
Rowland