我有一个默认状态,如下所示,我从postgres获取数据,考虑到我的照片数组为空,状态不会更新的情况。
原因是我直接访问了一些参数{this.state.media.photos[this.state.media.selectedMediaIndex].url}
我从行动中看到的是
action Object {type: "FETCH_MEDIA_FULFILLED", payload: Array[1]}
error TypeError: Cannot read property 'undefined' of null
action Object {type: "FETCH_MEDIA_REJECTED", payload: TypeError: Cannot read property 'undefined' of null at Media.render (http://localhost:3000/clien…}
这样做的正确方法是什么?设置状态时我应该创建一个默认对象,更新所有参数然后设置状态?
如果照片中至少有1个数组元素没有问题,唯一的问题是在照片列为空时的第一个状态。
状态:
this.state = {
media : {
video : "",
photos : [{
title : "",
url : "",
category : {
interior : false,
exterior : true,
closeup : false
},
display : {
preview : false,
featured : true,
none : false
},
size : "",
attribution_link : "",
attribution_text : "",
description : ""
}],
selectedMediaIndex : 0
}
}
一旦componentWillReceiveProps收到nextProps,我就会更新我的状态。
componentWillReceiveProps(nextProps){
if(nextProps.media.length){
this.setState({
media : nextProps.media[0]
})
}
}
连接器:
const mapStateToProps = function (store) {
return {
media: store.media.media
};
};
const PhotoConnector = Redux.connect(mapStateToProps)(Media);
export default class MediaConnector extends React.Component {
render() {
return (
<PhotoConnector media={this.props.media}/>
);
}
}
REDUCER:
export default function reducer(
state={
media: [],
fetching: false,
fetched: false,
error: null,
}, action) {
switch (action.type) {
case "FETCH_MEDIA": {
return {...state, fetching: true}
}
case "FETCH_MEDIA_REJECTED": {
return {...state, fetching: false, error: action.payload}
}
case "FETCH_MEDIA_FULFILLED": {
return {
...state,
fetching: false,
fetched: true,
media: action.payload,
}
}
}
return state
}
更新
我有办法不得错误,我基本上检查照片是否为空并为其设置默认状态数组。
componentWillReceiveProps(nextProps){
if(nextProps.media.length){
if(!nextProps.media.photos){
this.setState({
media : {
video : nextProps.media[0].video,
photos : [{
title : "",
url : "",
category : {
interior : false,
exterior : true,
closeup : false
},
display : {
preview : false,
featured : true,
none : false
},
size : "",
attribution_link : "",
attribution_text : "",
description : ""
}],
selectedMediaIndex : 0
}
})
}
else{
this.setState({
media : nextProps.media[0]
})
}
}
}
任何其他解决方案将不胜感激。
答案 0 :(得分:3)
为什么不只有默认道具?
PhotoConnector.defaultProps = {
media: {
video: [],
photos: [],
}
};
或者也许是默认商店?
class Media {
constructor(js = {}) {
this.video = js.video || [];
this.photos = js.photos || [];
}
}
state={
media: [new Media()],
}
case "FETCH_MEDIA_FULFILLED": {
return {
...state,
fetching: false,
fetched: true,
media: action.payload.map(m => new Media(m)),
}