【问题标题】:React/Redux: store is not updating between actions called from a single onClick eventReact/Redux:商店没有在从单个 onClick 事件调用的操作之间更新
【发布时间】:2018-05-30 09:45:32
【问题描述】:

目标

点击next按钮并向redux store发送两个动作:

  1. 首先,更新skipAmount 值。
  2. 然后使用更新后的skipAmount 值生成apiQuery(用于向服务器发出请求的字符串)。

问题

skipAmount 值未在操作 1 和 2 之间更新

示例

我创建了一个 CodeSandbox,它清楚地展示了我遇到的问题。请注意,skipAmount 的值在apiQuery 之前是100(或单击事件)。 https://codesandbox.io/s/o2vvpwqo9

代码

Index.js

import React from "react";
import ReactDOM from "react-dom";
import { Provider } from "react-redux";
import { createStore } from "redux";

import App from "./App";
import reducer from "./reducer";

const store = createStore(reducer);

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

App.js

import React from 'react';
import { connect } from 'react-redux';

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

const queryGenerator = props => `www.apiExample.com?skipAmount=${props.skipAmount}`;

const ConnectedApp = props => (
  <div className="App">
    <button
      onClick={() => {
        props.dispatch({ type: 'SET_SKIP_AMOUNT_PLUS_100' });
        props.dispatch({ type: 'SET_API_QUERY', payload: queryGenerator(props) });
      }
      }
    >
      Next
    </button>
    <p>Skip amount on redux: {props.skipAmount}</p>
    <p>Query being generated: {props.apiQuery}</p>
  </div>
);

export default connect(mapStateToProps)(ConnectedApp);

reducer.js

const reducerDefaultState = {
  skipAmount: 0,
  apiQuery: 'www.apiExample.com',
};

export default (state = reducerDefaultState, action) => {
  switch (action.type) {
    case 'SET_SKIP_AMOUNT_PLUS_100':
      return {
        ...state,
        skipAmount: state.skipAmount + 100,
      };
    case 'SET_API_QUERY':
      return {
        ...state,
        apiQuery: action.payload,

      };
    default:
      return state;
  }
};

【问题讨论】:

    标签: redux react-redux state


    【解决方案1】:

    App.js queryGenerator(props) 中,您从 onClick 传递未更改的道具。

    在重新渲染之前,道具不会从 SET_SKIP_AMOUNT_PLUS_100 更改。

    onClick={() => {
            props.dispatch({ type: 'SET_SKIP_AMOUNT_PLUS_100' });
            props.dispatch({ type: 'SET_API_QUERY', payload: queryGenerator(props) });
          }
    

    'SET_SKIP_AMOUNT_PLUS_100' 中,您正在更改 redux 状态。 (不是组件中的当前道具),

    并且在'SET_API_QUERY' 中,您正在使用组件道具(不是redux 中的内容),因为道具尚未更新。

    【讨论】:

    • 谢谢雅各布。对于如何在单个 onClick 事件中传递更新的道具,您有什么建议吗?
    • 不用担心。您可以通过在 p 标签中实现您想要的:queryGenerator(props.apiQuery} 如果您想将值保存在商店中,您可以在与SET_SKIP_AMOUNT_PLUS_100 相同的操作中更改 api_query
    • 再次感谢,但恐怕我认为这并不能真正解决问题。对于应用程序的几个部分来说,基于 onClick 事件发出 httpRequests 很重要(而且它并不总是像这个例子那么简单),你知道有没有其他方法(例如中间件)来拥有组件道具动作之间的更新?
    • 我不太确定您想要实现什么。如果您不想在同一操作中进行多项更改。并且您想在同一个 onClick/function 中使用更改后的商店,您唯一的选择是向您的操作发送回调函数。你真的不应该这样做。你能提供一个真实的例子,那么我可以更好地帮助你:)
    • 感谢 Jakob,非常感谢您的帮助。也许我还不够清楚。想象一下,您有一个带有“提交”按钮的搜索工具,可以一次加载 100 条记录。要查看更多内容,用户必须单击页面底部的“下一步”按钮。我希望“下一步”按钮将 skipAmount 更新 100,然后使用更新的跳过金额向服务器查询。可以单击“下一步”按钮跳过金额,然后单击“提交”按钮提出请求,但这对我来说似乎违反直觉。我将更新代码框以反映我的意思。
    猜你喜欢
    • 1970-01-01
    • 2019-11-06
    • 2020-06-10
    • 2020-02-06
    • 1970-01-01
    • 2016-12-18
    • 1970-01-01
    • 2018-01-14
    相关资源
    最近更新 更多