React-Redux:如何设置状态?

发布于 2025-01-15 14:51:10 字数 2447 浏览 0 评论 0原文

我试图理解其他人的代码,但很难理解 Redux 和 React 之间的交互。

在 React 页面上,我调用一个名为 getSubscriptionPlan 的 Redux 操作。在该 Redux 操作中,我看到它能够加载正确的数据(下面的 1 点)。这使用了一个减速器,我可以在其中再次确认正确的数据(下面的2点)。

然后逻辑返回到 React 页面(下面的 3 点)。我现在希望能够在 Redux 存储中找到前面提到的数据。但是,我找不到在任何地方列出的数据......不在 this.state (我期望的位置)中,也不在 this.props 中。减速器是否可能没有更新存储状态......?

我做错了什么以及如何获取下面的 3 点的数据?

React 页面:

import { connect } from "react-redux";
import { getSubscriptionPlan } from "../../../appRedux/actions/planAction";

async componentDidMount() {
    let { planId } = this.state;
    await this.props.getSubscriptionPlan(planId);

    // 3. I can't find the data anywhere here: not inside this.state and not inside this.props.

    this.setState({plan: this.state.plan});
}

componentDidUpdate(prevProps, prevState) {
    if (prevProps.payment.paymentData !== this.props.payment.paymentData) {
        this.setState({
            checkout: this.props.payment.paymentData,
            plan: this.props.payment.paymentData.plan,
        });
    }
}

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

const mapDispatchToProps = (dispatch) => {
    return bindActionCreators(
        { getSubscriptionPlan }, dispatch
    );
};

export default withRouter(
    connect(mapStateToProps, mapDispatchToProps)(Checkout)
);

Redux 操作:

export const getSubscriptionPlan = (id) => {
    let token = getAuthToken();
    return (dispatch) => {
        axios
            .get(`${url}/getSubscriptionPlan/${id}`, {
                headers: { Authorization: `${token}` },
            })
            .then((res) => {
                if (res.status === 200) {

                    // 1. From console.log(res.data) I know res.data correctly now contains the data

                    return dispatch({
                        type: GET_PLAN_SUCCESS,
                        payload: res.data,
                    });
            })
    };
};

Reducer:

export default function planReducer(state = initial_state, action) {
    switch (action.type) {
        case GET_PLAN_SUCCESS:

            // 2. I know action.payload, at this point contains the correct data.

            return { ...state, plan: action.payload };
        default:
            return state;
    }
}

I am trying to understand someone else their code but have difficulty understand the interaction between Redux and React.

On a React page, I invoke a Redux action called getSubscriptionPlan. Inside that Redux action, I see it is able to load the correct data (point 1 below). This uses a reducer, in which I can again confirm the correct data is there (point 2 below).

Then the logic returns to the React page (point 3 below). I now would expect to be able to find somewhere in the Redux store the previously mentioned data. However, I can't find that data listed anywhere... not in this.state (where I would expect it), nor in this.props. Did the reducer perhaps not update the store state...?

What am I doing wrong and how can I get the data to point 3 below?

React page:

import { connect } from "react-redux";
import { getSubscriptionPlan } from "../../../appRedux/actions/planAction";

async componentDidMount() {
    let { planId } = this.state;
    await this.props.getSubscriptionPlan(planId);

    // 3. I can't find the data anywhere here: not inside this.state and not inside this.props.

    this.setState({plan: this.state.plan});
}

componentDidUpdate(prevProps, prevState) {
    if (prevProps.payment.paymentData !== this.props.payment.paymentData) {
        this.setState({
            checkout: this.props.payment.paymentData,
            plan: this.props.payment.paymentData.plan,
        });
    }
}

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

const mapDispatchToProps = (dispatch) => {
    return bindActionCreators(
        { getSubscriptionPlan }, dispatch
    );
};

export default withRouter(
    connect(mapStateToProps, mapDispatchToProps)(Checkout)
);

Redux action:

export const getSubscriptionPlan = (id) => {
    let token = getAuthToken();
    return (dispatch) => {
        axios
            .get(`${url}/getSubscriptionPlan/${id}`, {
                headers: { Authorization: `${token}` },
            })
            .then((res) => {
                if (res.status === 200) {

                    // 1. From console.log(res.data) I know res.data correctly now contains the data

                    return dispatch({
                        type: GET_PLAN_SUCCESS,
                        payload: res.data,
                    });
            })
    };
};

Reducer:

export default function planReducer(state = initial_state, action) {
    switch (action.type) {
        case GET_PLAN_SUCCESS:

            // 2. I know action.payload, at this point contains the correct data.

            return { ...state, plan: action.payload };
        default:
            return state;
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

月竹挽风 2025-01-22 14:51:10

您对 Redux 的工作原理感到困惑。

Redux 不使用 React 组件状态。它单独管理状态,并将该状态作为 props 传递给组件。当您调用 getSubscriptionPlan 时,您将异步分派一个事件到 Redux,Redux 会处理该事件并更新减速器中的存储状态。该状态会传递给连接组件的 mapStateToProps 函数,映射到 props,然后作为 props 传递给您的组件。传递新的 props 会触发 componentDidUpdate 和组件的重新渲染。

这里有一些关键的事情。

  1. Redux 不会与组件状态交互,除非您使用从 Redux 传递的 props 显式设置状态。
  2. Redux 是异步的。这意味着当您通过调度对状态进行更改时,更改不会立即在组件中可用,而仅在传递新的 props 时才可用。它是事件驱动的,而不是数据绑定。因此,在您的代码中,您不会在 componentDidMount 中看到 plan 属性,因为当时 componentDidMount 还没有调用 getSubscriptionPlan发生了。

您应该会在 didUpdate 之前看到 componentDidUpdate 中的 this.propsrender 中填充的 prop。

使用 React 时,最好将组件视为 props 的基本功能,并附加一些额外的生命周期方法。

You are getting tripped up on how Redux works.

Redux does not use react component state. It manages state separately, and passes that state to components as props. When you call getSubscriptionPlan, you asynchronously dispatch an event to Redux, which handles the event and updates store state in the reducer. This state is the passed to the connected components mapStateToProps function, mapped to props, and then passed as props to your component. Passing new props triggers a componentDidUpdate and a rerender of the component.

A few key things here.

  1. Redux does not interact with component state unless you explicitly set state with props passed from Redux.
  2. Redux is asynchronous. That means that when you make a change to state via dispatch, the change is not immediately available in the component, but only available when new props are passed. It's event driven, not data binding. As a result, in your code you woun't see the plan prop in componentDidMount because at the time componentDidMount the call to getSubscriptionPlan hasn't happened.

You should see the prop populated in this.props in componentDidUpdate and in render before the didUpdate.

When working with react, it's best to think of components as basically functions of props with some extra lifecycle methods attached.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文