簡體   English   中英

在react構造函數中訪問props

[英]accessing props inside react constructor

我無法在使用redux概念實現的構造函數中獲取道具。

容器組件代碼

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獲取道具,即item,但在構造函數內部則不能。

並為操作編寫代碼,以查看redux實現是否正確,

    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}
}

最后,我的減速器如下所示

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;
    }
}

我用谷歌搜索沒有運氣,我不知道我在哪里犯了錯誤。 如果有人給我指出,那將是很大的幫助。 提前致謝。

您無法在構造函數中訪問props的原因是,在首次安裝組件之前,它只能被調用一次。

加載項目的操作在componentWillMount函數中調用,該函數在調用構造函數之后發生。

似乎您正在嘗試在mapStateToProps函數中設置默認值,但根本沒有使用它

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


    return {
        item: state.itemReducer
    };
}

我注意到的下一部分是您正在從redux獲取狀態,並試圖將其注入組件的本地狀態

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

混合使用redux狀態和組件狀態很少是一個好主意,應盡量避免。 它可能導致不一致,並且很難發現錯誤。

在這種情況下,我看不出無法用this.state.itemTitle替換this.state.itemTitle所有this.props.items.itemTitle並將其從組件狀態中完全刪除的任何原因。


意見

關於您的代碼,有些奇特的事情使我很難推斷出代碼的意圖。

首先是減速器

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對象,但是通常它代表了reducer的整個初始狀態,因此使用initialState.item對我來說很突出。 您可能正在為所有化簡器重用一個共享的初始狀態對象,所以我對此不太擔心。

什么使Object.assign調用非常混亂。 我不確定它的意圖是在狀態下輸出對象替換item ,或者是將action.item附加到數組,還是將具有單個項的數組作為結果狀態。 state = action.item部分對於操作的意圖也特別令人困惑。

PropTypes for UpdateItem進一步混淆了這PropTypes ,它要求item為數組

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

但是組件中的用法將其視為對象

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

來自評論的更新

這是我在評論中正在談論的一個示例 它是您代碼的簡化版本(我沒有您的所有組件。我還修改了一些東西來匹配我的個人風格,但希望您仍然可以看到正在發生的事情。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM