简体   繁体   English

为什么来自 Redux 商店的这个变量不在 React 页面的 `this.props` 中?

[英]Why is this variable from the Redux store not in the `this.props` on React page?

I have a variable that I believe is correctly written to my Redux store using a Redux action and reducer.我有一个变量,我相信它已使用 Redux 操作和减速器正确写入我的 Redux 商店。 But for some reason it never becomes part of the props on a React page.但出于某种原因,它永远不会成为 React 页面上的道具的一部分。 What could be the cause, given the code below?给定以下代码,可能是什么原因? I would expect this.props.transactionDetails and this.state.trans_status to be available within the render code block.我希望this.props.transactionDetailsthis.state.trans_statusrender代码块中可用。 The Redux store is functioning correctly for other variables/pages. Redux 存储对于其他变量/页面正常运行。

React Page:反应页面:

import { get_details } from "../../../appRedux/actions/transAction";

class DonePage extends Component {
    constructor(props) {
        super(props);
        this.state = {
            showLoader: true,
            transactionDetails: "",
            trans_status: "",
        };
    }

    async componentDidMount() {
        await this.props.get_details('abc1234');
    }

    componentDidUpdate(prevProps, prevState) {
        if (prevProps.transactionDetails !== this.props.transactionDetails) {
            console.log("Inside ComponentDidUpdate");
            // It never arrives here, perhaps suggesting the prop is never created in the store?

            this.setState({
                trans_status: this.props.transactionDetails.trans_status,
            });
        }
    }

    render() {
        console.log(JSON.stringify(this.state.trans_status);
        // returns "" instead of the value of the redux action/reducer
        console.log(JSON.stringify(this.props.transactionDetails);
        // returns undefined instead of the value of the redux action/reducer

        // What am I doing wrong? Why am I not getting the transactionDetails here?
    }
}

const mapStateToProps = (state) => {
    return {
        settings: state.settings,
        // the settings property works fine in this component
        transactionDetails: state.transactionDetails,
    };
};

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

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

Redux Action: Redux 行动:

export const get_details = (trans_id) => {
    let token = getAuthToken();
    return (dispatch) => {
        axios
            .get(`${url}/get_details/${trans_id}`, {
                headers: { Authorization: `${token}` },
            })
            .then((res) => {
                if (res.status === 200) {
                    console.log(JSON.stringify(res.data.data);
                    // returns {"trans_status":"paid","trans_due":"0"}
                    return dispatch({
                        type: DETAILS_SUCCESS,
                        payload: res.data.data,
                    });
                } else {
                    return dispatch({
                        type: DETAILS_ERROR,
                        payload: res.data.data,
                    });
                }
            })
    }
}

Reducer:减速器:

import {
    DETAILS_SUCCESS,
    DETAILS_ERROR,
} from "../constants";

const initial_state = {
    transactionDetails: [],
    transactionDetailsError: "",
};

export default function transactionsReducer(state = initial_state, action) {
    switch (action.type) {
        case DETAILS_SUCCESS:
            console.log(JSON.stringify(action.payload));
            // returns {"trans_status":"paid","trans_due":"0"}
            return { ...state, transactionDetails: action.payload };
        case DETAILS_ERROR:
            return { ...state, transactionDetailsError: action.payload };
        default:
            return state;
    }
};

Update In the reducers index file ( /reducers/index.js ) I have:更新在 reducers 索引文件 ( /reducers/index.js ) 中我有:

const reducers = combineReducers({
    variousVariables: variablesReducer,
    transactions: transactionsReducer,
});

It works if I change this to:如果我将其更改为:

const reducers = combineReducers({
    variousVariables: variablesReducer,
    transactionDetails: transactionsReducer,
});

On the Page, within render , this.props.transactionDetails now returns data:在页面上,在render中, this.props.transactionDetails现在返回数据:

{"transData":[],"transactionDetails":{"transaction_status":"paid","transaction_amount_due":"0"},"transactionDetailsError":"","otherData":"", etc.}

So transactionDetails is nested inside another transactionDetails and I need to call this.props.transactionDetails.transactionDetails or this.props.transactionDetails.transData .所以transactionDetails嵌套在另一个transactionDetails中,我需要调用this.props.transactionDetails.transactionDetailsthis.props.transactionDetails.transData However, I would like this to be this.props.transactions.transactionDetails and this.props.transactions.transData .但是,我希望这是this.props.transactions.transactionDetailsthis.props.transactions.transData

Can someone explain what is going on?有人可以解释发生了什么吗? I thought I could just name the keys in the reducers index file anything I like and that then defines the "path" of this.props.anythingilike .我想我可以随便命名 reducers 索引文件中的键,然后定义this.props.anythingilike的“路径”。

Why can I not just change the key in the reducers index file to get what I'm looking for?为什么我不能只更改 reducers 索引文件中的键来获取我要查找的内容? I guess I need to change something on the Page as well to make it the way I want?我想我还需要更改页面上的某些内容以使其成为我想要的方式吗? Because right now if I change the key in the reducers index file to transactions , then this.props.transactions is still undefined on the Page, while if that key is transactionDetails then this.props.transactionDetails does return the correct data.因为现在如果我将 reducers 索引文件中的键更改为transactions ,那么this.props.transactions在页面上仍然是undefined的,而如果该键是transactionDetails那么this.props.transactionDetails会返回正确的数据。

I found the solution to my question.我找到了我的问题的解决方案。 As suggested by several people there was details about the store setup that were of importance, particularly the setup of the reducers and the use of combineReducers .正如一些人所建议的那样,有一些关于 store 设置的细节很重要,尤其是 reducer 的设置和combineReducers的使用。

The setup of my reducers included:我的减速器的设置包括:

const reducers = combineReducers({
    ...,
    transactions: transactionsReducer,
});

To make it work, on the Page I only needed to change:为了让它工作,我只需要在页面上更改:

1-- this.props.transactionDetails to this.props.transactions (and this.props.transactions.transactionDetails if needed. 1-- this.props.transactionDetailsthis.props.transactions (如果需要,还有this.props.transactions.transactionDetails

2--The last line in the code block below needed to be transactions: state.transactions 2--下面代码块的最后一行需要是transactions: state.transactions

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

You can use it with the method compose from redux library.您可以将它与 redux 库中的 compose 方法一起使用。

import {compose} from "redux";

//your code

export default compose(
  withRouter,
  connect(mapStateToProps, mapDispatchToProps)
)(App);

get_details() is not an async function so no need to await I believe. get_details()不是异步 function 所以我相信不需要等待。

Additionally, you can check first if your props is updated on componentDidupdate like此外,您可以先检查您的道具是否在componentDidupdate上更新,例如

componentDidUpdate(prevProps, prevState) {
  console.log(this.props.transactionDetails)
  // if transactionDetails updated then you can perform setState
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM