首页 > 解决方案 > 为什么 react 组件没有从 redux 返回当前数据?

问题描述

我有一个与 redux 连接的反应应用程序。该组件有一个表单,该表单在提交表单时对 api 进行 PUT 调用。当我提交表单时,我可以看到 redux 得到相应更新,但是当我尝试将 redux 状态作为组件中的 prop 访问时,props 数据不返回当前数据并且关闭 1。例如,这里是我的 redux 商店中的数据:

Redux 商店:

还原商店

当我console.log("THIS PROPS: ", this.props)在我的组件中执行时,我看到它accountError显示为null

在此处输入图像描述

当我第二次再次发送操作时,我才看到我正在从我的 props 中的 redux 获取数据:

在此处输入图像描述

这是我目前拥有的代码:

组织账户.js

import { registerOrgAccount, getListOfOrgsAndAccts } from "../../store/actions";

handleSubmit = () => {
  this.props.registerOrgAccount(this.state)
  console.log("THIS PROPS: ", this.props)
  if(this.props.accountError === null) {
    this.toggleTab(this.state.activeTab + 1);
  }
};

<Link
  to="#"
  className="btn w-lg"
  onClick={() => {
    if (this.state.activeTab === 1) {
      this.handleSubmit();
    }
  }}
>
  Next
</Link>

const mapStatetoProps = (state) => {
  const { accounts, accountError, loading } = state.OrgAccount;
  return { accounts, accountError, loading };
};

const mapDispatchToProps = (dispatch) => {
  return {
      getListOfOrgsAndAccts: () => {
        dispatch(getListOfOrgsAndAccts())
    },
     registerOrgAccount: (data) => {
        dispatch(registerOrgAccount(data))
     },
     
  }
}

export default connect(mapStatetoProps, mapDispatchToProps)(OrgAccount);

减速器:

const initialState = {
    accountError: null, accountsError: null, message: null, loading: null
}

const orgAccount = (state = initialState, action) => {
    switch (action.type) {
        case REGISTER_ORG_ACCOUNT:
            state = {
                ...state,
                account: null,
                loading: true,
                // accountError: null
            }
            break;
       
        case REGISTER_ORG_ACCOUNT_SUCCESSFUL:
            state = {
                ...state,
                account: action.payload,
                loading: false,
                accountError: null
            }
            break;
        case REGISTER_ORG_ACCOUNT_FAILED:
            state = {
                ...state,
                loading: false,
                accountError: action.payload ? action.payload.response : null
            }
            break;
        ...
        default:
            state = { ...state };
            break;
    }
    return state;
}

export default orgAccount;

行动

export const registerOrgAccount = (account) => {
    return {
        type: REGISTER_ORG_ACCOUNT,
        payload: { account }
    }
}

export const registerOrgAccountSuccessful = (account) => {
    return {
        type: REGISTER_ORG_ACCOUNT_SUCCESSFUL,
        payload: account
    }
}

export const registerOrgAccountFailed = (error) => {
    return {
        type: REGISTER_ORG_ACCOUNT_FAILED,
        payload: error
    }
}

Saga.js

import { registerOrgAccountSuccessful, registerOrgAccountFailed, getListOfOrgsAndAcctsSuccessful, getListOfOrgsAndAcctsFailed } from './actions';
import { putOrgAccount } from '../../../helpers/auth_helper';

function* registerOrgAccount({ payload: { account } }) {
    try {
        const response = yield call(putOrgAccount, {
            orgId: account.orgId,
            accountNumber: account.accountNumber,
            accountName: account.accountName,
            accountCode: account.accountCode,
            urlLink: account.urlLink,
            location: account.location,
            accountType: account.accountType,
            address: account.address,
            city: account.city,
            state: account.state,
            zip: account.zip,
            country: account.country,
            email: account.email,
            eula: "blah"
        });
        yield put(registerOrgAccountSuccessful(response));
    } catch (error) {
        yield put(registerOrgAccountFailed(error));
    }
}

标签: javascriptreactjsreduxecmascript-6react-redux

解决方案


要了解这里的根本原因,我认为了解一些关于不变性和 React 如何重新渲染的知识会有所帮助。简而言之,React 会在检测到引用更改时重新渲染。这就是为什么改变一个道具,不会触发重新渲染。

考虑到这一点,在您调用 handleSubmit 时,this.props.accountError只是对内存中某个值的引用。当您调度您的操作并更新您的状态时,将创建一个新的引用,这将触发您的组件的重新渲染。但是,传递给您的元素的 handleSubmit 函数仍然引用旧的 this.props.accountError,这就是它仍然为空的原因。

您可以通过在 componentDidUpdate 生命周期方法中实施检查来解决此问题。例如这样的:

componentDidUpdate(prevProps) {
  if (prevProps.accountError === null && this.props.accountError !== null) {
    this.toggleTab(this.state.activeTab + 1)
  }
}

推荐阅读