【问题标题】:How to properly dispatch the same action twice in a single React Component如何在单个 React 组件中正确分派相同的操作两次
【发布时间】:2019-06-14 08:00:57
【问题描述】:

我正在尝试了解在我的 react 应用程序中使用 redux 所面临的数据获取挑战的最佳方法。

简而言之,我需要分派相同的提取(在本例中为fetchPlayerSeasonStats)两次,并保存两次提取的数据。第一次获取获取单个玩家的统计信息(通过获取可选的第一个参数thisPlayerId),第二次获取省略参数并获取更大的数据集。

我在下面尝试做的事情如下:

(a) 第一次获取playerSeasonStats

(b) 在componentDidUpdate() 中,检查第一次提取是否已完成(if 条件检查数组长度)。

(c) 如果条件满足,则使用状态变量thisPlayersSeasonStats 来存储原始获取的数据。

(d) 然后,使用另一个调度的操作重新获取更大的数据集。

...除了我收到的警告说“不要更新 componentDidMount 中的状态”,一般来说,我不确定这种方法是否正确或者它是否是“反模式”/错误的 React/ Redux 编码风格。我想确保我这样做是正确的,因此对以下代码(特别是 componentDidUpdate() 函数)的任何审查将不胜感激!

谢谢!

// Import React Components
import React, { Component } from 'react';
import { connect } from 'react-redux';

// Import Fetches
import { fetchPlayerSeasonStats } from '../../../actions/...';

// Create The Component
class MyComponentHere extends Component {
    constructor(props) {
        super(props);
        this.state = {
            thisPlayerSeasonStats: []
        };
    }

    componentDidMount() {
        let thisPlayerId = this.props.playerInfo._id;
        this.props.dispatch(fetchPlayerSeasonStats(thisPlayerId, this.props.appSeason.value));
    }

    componentDidUpdate(prevProps) {
        console.log('prevProps: ', prevProps);
        if (this.props.appSeason !== prevProps.appSeason) { this.refetchTeamsStats(); }
        if (prevProps.playerSeasonStats.length === 0 && this.props.playerSeasonStats.length === 1) {
            this.setState({ thisPlayerSeasonStats: this.props.playerSeasonStats });
            this.props.dispatch(fetchPlayerSeasonStats(null, this.props.appSeason.value));
        }
    }

    render() {
        // Handle Initial Loading Of Data
        if (this.state.thisPlayerSeasonStats.length === 0) { return <LoadingSpinner />; }

        // The Return
        return (
            <div> Return Dont Matter For here </div>
        );
    }
}

function mapStateToProps(reduxState) {
    return {
        playerSeasonStats: reduxState.playerSeasonStatsReducer.sportsData,
        loading: (reduxState.playerSeasonStatsReducer.loading),
        error1: reduxState.playerSeasonStatsReducer.error
    };
}

export default connect(mapStateToProps)(MyComponentHere);

【问题讨论】:

  • 如果你已经在你的应用程序中使用 redux,应该看看 redux-thunk 或 redux-saga,对于小范围 redux-thunk 对你来说已经足够了,尝试调用请求并处理thunk 中的所有逻辑然后只是 dispatch 一次到 reducer 与完整数据。
  • 不要读它。这是随机的。我认为您应该考虑以不同的方式对其进行架构,尽管您需要两次提取,但它似乎属于同一操作。您应该创建一个元操作,将这两个调度合并为一个,然后视图只需在挂载时触发一个操作

标签: reactjs redux


【解决方案1】:

答案很简单。

让我们看看redux-thunk 是如何工作的。

Redux Thunk 中间件允许您编写返回函数而不是动作

的动作创建器

我认为这就是 fetchPlayerSeasonStats 本质上所做的。它返回一些获取玩家的异步函数。 Redux-thunk 有助于调度它(我认为您使用 Redux-thunk。如果您使用其他一些异步中间件,它应该基本相同)。

所以我们可以编写动作创建器,它会返回函数(如fetchPlayerSeasonStats),但内部不会调度动作,而是调度另一个函数。所以我们会有函数调度函数来调度动作:-)

例如

fetchAllPlayerStats (thisPlayerId, appSeasonValue) => dispatch => {
    dispatch(fetchPlayerSeasonStats(thisPlayerId, appSeasonValue));
    dispatch(fetchPlayerSeasonStats(null, appSeasonValue));
}

然后您可以使用componentWillMount 中的this.props.dispatch(fetchAllPlayerStats(thisPlayerId, this.props.appSeason.value)) 一次获取所有数据。

提示。 fetchAllPlayerStats 的当前实现将立即获取所有数据。如果您添加 async/await 关键字,您将首先获得单个玩家的数据,然后获得更大的数据集。修改后的版本看起来像

fetchAllPlayerStats (thisPlayerId, appSeasonValue) => async dispatch => {
    await dispatch(fetchPlayerSeasonStats(thisPlayerId, appSeasonValue));
    await dispatch(fetchPlayerSeasonStats(null, appSeasonValue));
}

这里是简单的example 展示逻辑

【讨论】:

  • 我已经在我的应用程序上安装了 redux thunk。是的,fetchPlayerSeasonStats 是一个同步函数,用于获取该数据。
  • 很可能是的,两个数据集将被加载到同一个地方。我建议创建 2 个不同的操作:例如 FETCH_PLAYER_STATSFETCH_ALL_PLAYERS_STATS。第一个动作将由fetchPlayerSeasonStats 发送,第二个动作由fetchAllPlayersSeasonStats 发送(是的,您需要额外的动作创建者)。并且在 reducer 中分别处理这两个动作。
猜你喜欢
  • 2019-03-19
  • 2023-02-04
  • 1970-01-01
  • 1970-01-01
  • 2021-02-15
  • 2017-06-20
  • 1970-01-01
  • 2016-11-18
  • 2018-01-27
相关资源
最近更新 更多