【问题标题】:React | Redux | Thunk - How data should be loaded from within a component?反应 |还原 | Thunk - 如何从组件中加载数据?
【发布时间】:2016-12-06 09:50:33
【问题描述】:

我有一个组件,它使用 componentWillMount 通过 redux 进行 API 调用以获取数据并更新状态。

在调用此方法之前,我需要访问数据库并获取一个属性,我将根据该属性决定是否应该进行数据检索(来自第 1 段)。

我想做什么(使用承诺) -

  1. 获取属性(来自第 2 段)
  2. 然后,如果需要数据,则分派正常流程(第 1 段)。
  3. 如果不需要数据,请继续。

我的问题是您的意见应该放在哪里。

一方面,通过商店来做这件事感觉有点过头了。另一方面,任何机会我都会遇到副作用问题。 此外,我可以在组件或动作创建器中实现逻辑。你认为什么最好?

附加信息: 1.我正在使用redux-thunk。更改为 sagas 是不可能的。 2.我正在检查的属性在1个reducer中,而需要获取的数据在另一个reducer中(不知道,对于某些解决方案可能有问题。)。

选项 1:

import {getData} from '....../dataActions';
import {getToken} from '......../userActions';

const MegaComponent extends React.Component {
    componentWillMount() {
    getToken(uid)
        .then(shouldUpdate => {
        if (shouldUpdate) {
            getData(uid);
        } else {
            console.log('no need to get data');
        }
      }) 
  }
}

funciton mapStateToProps(state, ownProps) {
    return {
    user: state.user
  }
}

function mapDispatchToProps(dispatch) {
    return {
    getToken: (uid) => dispatch(getToken(uid)),
    getData: (uid) => dispatch(getData(uid))
  };
}

export default connect(mapStateToProps, mapDispatchToProps)(MegaComponent);

选项2(我认为应该做的)

export function getToken(uid) {
    return dispatch => {
    return api.getToken(uid)
        .then(token => {
        if (token === 'what it should') {
            return {type: 'NO_DATA_CHANGE_NEEDED', action: null};
        } else {
            // the action that handle getting data is in a different action creator.
            // I either import it here and call it, or there's a better way.
        }
      })
  }
}

更新

这对未来的访客可能会派上用场 - getting state inside an action creator

【问题讨论】:

    标签: reactjs redux redux-thunk


    【解决方案1】:

    嘿,这是一个非常广泛的问题,但我想就如何解决它给出一个简短的建议,尽管我不太确定我是否完全正确。

    所以我首先要分离第 1 点(数据库调用)和第 2 点(其他所有内容)的关注点

    您可以先编写一个组件包装器 (HoC),它只执行数据库调用以获取进一步处理所需的道具。

    从 db 获取数据后,您可以使用数据作为 prop 渲染 InnerComponent,并通过检查注入的 prop 并触发其他操作来执行您需要的所有其他操作。

    【讨论】:

    • 有趣的方法!可能是一个解决方案。我会尝试在问题中添加一些代码。
    • 你好,我已经添加了一些代码,认为它可能会有所帮助
    • 是的,我看到您在需要时调度 getData(),但是如何将数据返回到您的组件?数据保存在存储中?但是您不会将该状态映射到道具。因此,即使您更改了数据,如何将更新后的数据发送到您的组件中?
    • 我故意省略了那部分,试图使代码更易于阅读。我想我将实现选项 2,我将导入 otherAction 创建者并从 getToken 中调用 getData。 getData 操作是处理您在之前评论中提到的状态更新的操作。您对我的解决方案有何看法?
    【解决方案2】:

    我不会让我的组件处理逻辑。让您的组件全部与 View 有关。将组件视为时间点状态的可视化表示。

    componentWillMount 中,您可以检查数据是否存在,如果不存在,则调用您的操作,该操作将通过 API 获取数据并将数据传递给减速器。减速器将“更新”状态。

    调度调用应该从actions.js而不是你的组件调用。

    【讨论】:

      【解决方案3】:

      所以,我的感觉是对的 - 选项 2 是。就像@guruPitka 建议的那样。

      在我的动作创建器(由组件调用)中,我获取当前的应用程序状态,进行 API 调用,比较令牌并采取相应的行动。

      export function getToken(uid) {
          return (dispatch, getState) => {
              const currentToken = getState().user.token;
      
              return api.lastAppLaunch(uid)
                  .then(newToken => {
                      if (newToken === currentToken) {
                          // All is good, carry on.
                      } else {
                          dispatch(getData(uid)); //getData is from a different action creator.
                      }
                  });
          }
      }
      

      以及组件中的调用——

      this.props.getToken(uid);
      

      【讨论】:

        猜你喜欢
        • 2017-04-04
        • 2017-05-12
        • 2019-01-02
        • 1970-01-01
        • 1970-01-01
        • 2019-10-10
        • 1970-01-01
        • 2019-05-24
        • 1970-01-01
        相关资源
        最近更新 更多