分配了Redux操作后,点击按钮不起作用

时间:2019-12-03 13:11:07

标签: reactjs redux

我需要一些有关此Redux问题的帮助。在这里,我有一个APP.js代码,该代码从名为duck.js的文件中调用了动作。

import {
  selectBaseCurrency,
  selectExchangeCurrency,
  selectExhangeRate,
  setBaseCurrency, //calling this action
  initialState,
} from "./configureStore/duck";

在这段代码中,我指定了mapDispatchToProp来分派动作。

const mapDispatchToProps = (dispatch,ownProps)=> ({
  onClick: () => dispatch(setBaseCurrency(ownProps.baseCurrency)),
});

我也将它连接到connect()。

export default connect(
  state => ({
    exchangeRate: selectExhangeRate(state),
    exchangeCurrency: selectExchangeCurrency(state),
    baseCurrency: selectBaseCurrency(state)
  }), mapDispatchToProps
)(App);

但是,由于某种原因,当我单击按钮时,该值不会根据输入内容进行更新。按钮代码如下:

 <button onClick={() => onClick("USD")}>
        Change Currency Value
 </button>

我错过了正确分发此代码的代码吗?这可能是什么问题。

在下面,我附上完整的鸭子以及App.js以获得更多参考。

App.js:

import React, { useEffect, useState } from "react";
import { PropTypes } from "prop-types";
import { connect } from "react-redux";
import {
  selectBaseCurrency,
  selectExchangeCurrency,
  selectExhangeRate,
  setBaseCurrency, //calling this action
  // setExchangeCurrency, 
  // setExchangeRate, 
  initialState,
} from "./configureStore/duck";

const App = ({
  exchangeRate,
  exchangeCurrency,
  baseCurrency,
  onClick
}) => {
  return (
    <div>
      <div>
        <b>Exchange Rate</b>: {exchangeRate}
      </div>
      <div>
        <b>Exchange Currency</b>: {exchangeCurrency}
      </div>
      <div>
        <b>Base Currency</b>: {baseCurrency}
      </div>
      <button onClick={() => onClick("USD")}>
        Change Currency Value
      </button>
    </div>
  );
};
App.propTypes = {
  exchangeRate: PropTypes.number,
  exchangeCurrency: PropTypes.string,
  baseCurrency: PropTypes.string,
  setBaseCurrency: PropTypes.func.isRequired,
  // setExchangeCurrency: PropTypes.func.isRequired,
  // setExchangeRate: PropTypes.func.isRequired,
  dispatch: PropTypes.func.isRequired
};
App.defaultProps = {
  exchangeRate: initialState.exchangeRate,
  exchangeCurrency: initialState.exchangeCurrency,
  baseCurrency: initialState.baseCurrency
};

const mapDispatchToProps = (dispatch,ownProps)=> ({
  onClick: () => dispatch(setBaseCurrency(ownProps.baseCurrency)),
  // on: setExchangeCurrency,
  // setExchangeRate: setExchangeRate
});

export default connect(
  state => ({
    exchangeRate: selectExhangeRate(state),
    exchangeCurrency: selectExchangeCurrency(state),
    baseCurrency: selectBaseCurrency(state)
  }), mapDispatchToProps
)(App);

duck.js

import { defineAction } from "redux-define";
import { createAction, handleActions } from "redux-actions";

export const initialState = {
  exchangeRate: 3.06,
  baseCurrency: "SGD",
  exchangeCurrency: "MYR"
};

//Action-types
export const SET_EXCHANGE_RATE = defineAction("SET_EXCHANGE_RATE");
export const SET_BASE_CURRENCY = defineAction("SET_BASE_CURRENCY");
export const SET_EXCHANGE_CURRENCY = defineAction("SET_EXCHANGE_CURRENCY");

//Action-creators
export const setExchangeRate = createAction(
  SET_EXCHANGE_RATE,
  params => params
);
export const setExchangeCurrency = createAction(
  SET_EXCHANGE_CURRENCY,
  params => params
);
export const setBaseCurrency = createAction(
  SET_BASE_CURRENCY,
  params => params
);

//reducer
const reducer = handleActions(
  {
    [setExchangeRate]: (state, { exchangeRate }) => ({
      ...state,
      exchangeRate
    }),
    [setExchangeCurrency]: (state, { exchangeCurrency }) => ({
      ...state,
      exchangeCurrency
    }),
    [setBaseCurrency]: (state, { baseCurrency }) => ({
      ...state,
      baseCurrency
    })
  },
  initialState
);
export default reducer;

//Selector
export const selectExhangeRate = state => state.exchangeRate;
export const selectExchangeCurrency = state => state.exchangeCurrency;
export const selectBaseCurrency = state => state.baseCurrency;

编辑:作为附加信息,这是我的沙盒链接:https://codesandbox.io/s/todoapp-with-redux-and-normalized-store-jkp8z

这是我的github链接: https://github.com/sc90/test-sandbox

1 个答案:

答案 0 :(得分:1)

因此,这里至少有两个问题,我将尝试一一解释,我不确定您使用的这些框架是如何交互的,但是这里有几点至少可以解决您的问题。

  1. 您的reducer尝试提取{ baseCurrency },但这不是您的操作的属性。相反,您需要在此处提取payload,如下所示:{ payload },此payload值将包含您的baseCurrency,并将其正确保存在化简器中,您应该返回{ {1}}

  2. 您的选择器试图直接从{ ...state, baseCurrency: payload }变量中读取数据,但是这个选择器包含在您发送到state的键下的化简器,在这种情况下,您称为化简器{{1 }},因此您需要选择combineReducers

  3. 这样的状态

请参阅我的Sandbox叉,其中我已为您修复了baseCurrency案例: https://codesandbox.io/s/todoapp-with-redux-and-normalized-store-ih79q