在React组件中订阅Redux动作

7
我有一个异步thunk,它从Web服务中获取一些信息,它可以派发三种类型的操作。
FETCH_REQUESTED
FETCH_SUCCEEDED
FETCH_FAILED

最终,如果成功了,它会返回实际的响应或错误对象。

我有一个组件,应该通过订阅FETCH_FAILED动作来检测操作是否失败,并根据错误类型(404/401和其他状态代码)显示错误消息。

export const fetchData = () => {
    return async (dispatch, getState) => {
        const appState = getState();

        const { uid } = appState.appReducer;

        await dispatch(fetchRequested());

        try {
            const response = await LookupApiFactory().fetch({ uid });

            dispatch(fetchSucceeded(response));

            return response;
        } catch (error) {
            dispatch(fetchFailed());

            return error;
        }
    }
}

我对redux和react还比较陌生,所以不确定是否朝着正确的方向前进,希望得到帮助。


1
你不需要订阅该操作,而是将你的组件映射到存储中。当存储被更新时,你的组件会相应地重新渲染。你可以使用mapStateToProps来实现这一点。 - Sujit.Warrier
是的,我理解这一点,当我需要显示文本值或类似的内容时,这样做是完全可以的,但当发生某个操作时,我需要根据其结果运行一些代码,不确定该如何实现。 - animaonline
这段代码是在普通类中而不是 React 组件中吗? - Sujit.Warrier
是的,它在一个单独的类中。 - animaonline
我想我的问题跟你有点相似——我需要在API成功调用时调用一个“成功”函数。然而,我需要监听该分发的操作,以便我可以进行有意义的UI更改(在我的情况下,关闭模态窗口)。这不是真正属于redux状态中的内容。在Angular的ngxs状态管理库中,您可以订阅存储,当特定动作被分派时会得到通知。我基本上需要在这里做同样的事情,但使用redux。我目前正在使用回调,但这很糟糕。 - Tom
3个回答

5
为了实现一个适当的redux回调和存储机制,您需要一个存储库来保存所有数据,。
const store = createStore(todos, ['Use Redux'])

然后,您将数据发送到存储中。
store.dispatch({
  type: 'FETCH_FAILED',
  text: reposnse.status //Here you should give the failed response from api
});

然后,您可以使用订阅函数从存储中获取值,并在任何组件中使用。每当调度操作并且状态树的某个部分可能已更改时,它将被调用。

store.subscribe(()=>{
  store.getState().some.deep.property
})

这是 Redux 的一个简单实现。随着您的应用程序变得更加复杂,您会希望将您的 reducing 函数拆分成独立管理状态不同部分的函数,使用 combineReducers。您可以从 redux.js 网站 获取更多信息。


0

最常见的方法是使用react-redux库中的connect函数。这是一个高阶组件,它订阅状态变化。请查看此库,此外它还允许您将操作创建者绑定到分派,从而使您能够从组件中分派操作。

您可以像这样使用它:

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

const MyComponent = ({ data, error }) => (
  <div>
    {error && (
      <span>Error occured: {error}</span>
    )}

    {!error && (
      <pre>{JSON.stringify(data, null, 2)}</pre>
    )}
  </div>
);

const mapStateToProps = (state) => ({
  data: state.appReducer.data,
  error: state.appReducer.error
});

export default connect(mapStateToProps)(MyComponent);

你可以在jsx中使用条件渲染,就像我上面展示的那样,或者使用守卫语句,像这样:

const MyComponent = ({ data, error }) => {
  if (error) {
    return (
      <span>Error occured: {error}</span>
    );
  }

  return (
    <pre>
      {JSON.stringify(data, null, 2)}
    </pre>
  );
}

0
假设使用reducers,
对于FETCH_FAILED动作,您可以放置一些有意义的标志,指示存在某些故障。根据该标志,您可以显示错误消息或执行其他操作。
const testReducers =(state,actione)=>{

    case 'FETCH_FAILED' : {

        return {
            ...state,{ error_in_response : true }
        }
    };

    default : return state;
}

在你的容器中,你可以获取那个标记并将其传递给你的组件。

假设使用combineReducers来合并reducers;

const mapStateToProps=(state)=>{

    return {
        error_in_response : state.testReducers.error_in_response
    }
}
connect(mapStateToProps)(yourComponent)

在您的组件中,可以使用 this.props.error_in_response 来访问它。

是的,但是检测到标志已设置并显示警报的正确位置是什么? - animaonline
这将reducer映射到props,但是基于更改,我在哪里显示警报? - animaonline
在你的组件中,当你使用redux-connect传递connected flag时。 - RIYAJ KHAN
在渲染方法内部? - animaonline
1
您可以根据组件挂载/卸载顺序在其中或其他生命周期基础上使用。 - RIYAJ KHAN

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接