访问内部反应构造函数的道具 [英] accessing props inside react constructor

查看:74
本文介绍了访问内部反应构造函数的道具的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我无法在构造函数中获得使用redux概念实现的道具。

I am unable to get props inside constructor that I have implemented using redux concept.

容器组件代码

class UpdateItem extends Component{
    constructor(props) {
    super(props);
    console.log(this.props.item.itemTitle) // output: undefined
    this.state = {
        itemTitle: this.props.item.itemTitle,
        errors: {}
    };

    this.handleChange = this.handleChange.bind(this);
}

handleChange(e) {
    //If the input fields were directly within this
    //this component, we could use this.refs.[FIELD].value
    //Instead, we want to save the data for when the form is submitted
    let state = {};
    state[e.target.name] = e.target.value.trim();
    this.setState(state);
}

    handleSubmit(e) {
    //we don't want the form to submit, so we pritem the default behavior
    e.preventDefault();

    let errors = {};
    errors = this._validate();
    if(Object.keys(errors).length != 0) {
        this.setState({
            errors: errors
        });
        return;
    }
    let itemData = new FormData();
    itemData.append('itemTitle',this.state.itemTitle)

    this.props.onSubmit(itemData);
}

    componentDidMount(){
        this.props.getItemByID();
    }

    componentWillReceiveProps(nextProps){
        if (this.props.item.itemID != nextProps.item.itemID){
            //Necessary to populate form when existing item is loaded directly.
            this.props.getItemByID();
        }
    }


    render(){

        let {item} = this.props;
        return(
            <UpdateItemForm
            itemTitle={this.state.itemTitle}
            errors={this.state.errors}
            />
        );
    }
}

UpdateItem.propTypes = {
    item: PropTypes.array.isRequired
};

function mapStateToProps(state, ownProps){
    let item = {
        itemTitle: ''
    };


    return {
        item: state.itemReducer
    };
}

function mapDispatchToProps (dispatch, ownProps) {
    return {
        getItemByID:()=>dispatch(loadItemByID(ownProps.params.id)),
        onSubmit: (values) => dispatch(updateItem(values))
    }
}

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

在render()方法中,我能够从redux获取道具,即物品,而不是内部构造函数。

Inside render() method am able to get the props i.e. item from the redux but not inside constructor.

用于查看redux实现是否正确的操作的代码,

And code for the actions to see if the redux implementation correct or not,

    export function loadItemByID(ID){
        return function(dispatch){
            return itemAPI.getItemByID(ID).then(item => {
                dispatch(loadItemByIDSuccess(item));
            }).catch(error => {
                throw(error);
            });
        };
    }

export function loadItemByIDSuccess(item){
    return {type: types.LOAD_ITEM_BY_ID_SUCCESS, item}
}

最后我的reducer看起来如下,

Finally my reducer looks as follows,

export default function itemReducer(state = initialState.item, action) {
    switch (action.type) {
        case types.LOAD_ITEM_BY_ID_SUCCESS:
            return Object.assign([], state = action.item, {
                item: action.item
            });
        default:
            return state;
    }
}

我用谷歌搜索得到没有运气的答案,我不知道我犯了什么错误。如果有人指出我这将是一个很大的帮助。在此先感谢。

I have googled to get answers with no luck, I don't know where i made a mistake. If some one point out for me it would be a great help. Thanks in advance.

推荐答案

您无法访问构造函数中的道具的原因是它只被调用一次,之前组件首次安装。

The reason you can't access the props in the constructor is that it is only called once, before the component is first mounted.

加载项目的操作在 componentWillMount 函数中调用,该函数发生在调用构造函数。

The action to load the item is called in the componentWillMount function, which occurs after the constructor is called.

看起来你试图在 mapStateToProps 函数中设置一个默认值但是不是完全不使用它

It appears like you are trying to set a default value in the mapStateToProps function but aren't using it at all

function mapStateToProps(state, ownProps){
    // this is never used
    let item = {
        itemTitle: ''
    };


    return {
        item: state.itemReducer
    };
}

我注意到的下一部分是你从redux采取的状态并尝试将它注入组件的本地状态

The next part I notice is that your are taking the state from redux and trying to inject it into the component's local state

this.state = {
    itemTitle: this.props.item.itemTitle,
    errors: {}
};

混合redux状态和组件状态很少是一个好主意,应该尽量避免。它可能导致不一致并且很难找到错误。

Mixing redux state and component state is very rarely a good idea and should try to be avoided. It can lead to inconsistency and and hard to find bugs.

在这种情况下,我认为没有任何理由你无法替换<$ c的所有用途$ c> this.state.itemTitle with this.props.items.itemTitle 并将其从组件状态中完全删除。

In this case, I don't see any reason you can't replace all the uses of this.state.itemTitle with this.props.items.itemTitle and remove it completely from the component state.

你的代码有一些特殊的东西让它变得非常困难让我推断出代码背后的意图。

There are some peculiar things about your code that make it very difficult for me to infer the intention behind the code.

首先是减速器

export default function itemReducer(state = initialState.item, action) {
    switch (action.type) {
        case types.LOAD_ITEM_BY_ID_SUCCESS:
            return Object.assign([], state = action.item, {
                item: action.item
            });
        default:
            return state;
    }
}

您还没有显示 initialState object,但通常它表示reducer的整个初始状态,因此使用 initialState.item 对我来说很突出。你可能正在为所有的reducers重用一个共享的初始状态对象,所以我不太关心这个。

You haven't shown the initialState object, but generally it represents the whole initial state for the reducer, so using initialState.item stands out to me. You may be reusing a shared initial state object for all of the reducers so I'm not too concerned about this.

这是多么令人困惑的事情Object.assign 调用。我不确定它的目的是在状态下输出替换 item 的对象,或者是否要附加 action.item 到一个数组,或者将一个数组作为结果状态。 state = action.item 部分对于操作的意图也特别令人费解。

What is very confusing the Object.assign call. I'm not sure it the intention is to output an object replacing item in the state, or if it is to append action.item to an array, or to have an array with a single item as the resulting state. The state = action.item part is also particularly puzzling as to it's intention in the operation.

这是进一步的对于 UpdateItem PropTypes 感到困惑,需要 item 数组

This is further confused by the PropTypes for UpdateItem which requires item to be an array

UpdateItem.propTypes = {
    item: PropTypes.array.isRequired
};

但组件中的用法将其视为对象

But the usage in the component treats it like and object

this.state = {
  // expected some kind of array lookup here |
  //                          V---------------
    itemTitle: this.props.item.itemTitle,
    errors: {}
};






从评论中更新



以下是我在评论中谈论的内容 。这是你的代码的简化版本(我没有你所有的组件。我也修改了一些符合我个人风格的东西,但希望你仍然可以看到发生了什么。


Update from comments

Here is a example of what I was talking about in the comments. It's a simplified version of your code (I don't have all your components. I've also modified a few things to match my personal style, but hopefully you can still see what's going on.

这篇关于访问内部反应构造函数的道具的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆