[英]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.