Javascript 获取数据后的处理状态-React

Javascript 获取数据后的处理状态-React,javascript,reactjs,react-redux,Javascript,Reactjs,React Redux,我有一个如下所示的默认状态,我正在从postgres获取数据,考虑到我的照片数组为空的情况,状态不会得到更新 原因是我正在直接访问一些参数,{this.state.media.photos[this.state.media.selectedMediaIndex].url} 我从行动中看到的是 action对象{type:“FETCH\u MEDIA\u completed”,有效负载:数组[1]} 错误类型错误:无法读取null的属性“未定义” action对象{type:“FETCH_MEDI

我有一个如下所示的默认状态,我正在从postgres获取数据,考虑到我的照片数组为空的情况,状态不会得到更新

原因是我正在直接访问一些参数,
{this.state.media.photos[this.state.media.selectedMediaIndex].url}

我从行动中看到的是

action对象{type:“FETCH\u MEDIA\u completed”,有效负载:数组[1]}

错误类型错误:无法读取null的属性“未定义”

action对象{type:“FETCH_MEDIA_REJECTED”,负载:TypeError:无法在MEDIA.render读取null的属性“undefined”(http://localhost:3000/clien…}

正确的方法是什么?在设置状态时,我应该创建一个默认对象,更新所有参数,然后设置状态吗

如果至少有1个照片数组元素,则没有问题,唯一的问题是照片列为null时处于第一个状态

声明:

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接收到下一步,我将更新我的状态

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

更新

我找到了一种不获取错误的方法,我基本上是检查照片是否为null,并为其设置默认状态数组

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

任何其他解决方案都将受到欢迎。

为什么不使用默认道具

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

当您用[react-redux]标记它时,我希望在某处看到一个减速机,就是[react-redux]标记正确吗?是的@Icepickle,很抱歉。我刚刚用reducer更新了代码。好的,那么下一个问题是为什么你不使用连接的组件?@Icepickle我刚刚用添加
连接器更新了问题,这就是你所说的吗?你不应该在componentWillReceiveProps中设置状态。在redux中状态的唯一来源是减缩器。好的,我想在
组件WillReceiveProps
中更多地处理这个问题,这不是延迟的问题,但是如果数组本身在数据库中是空的。这就是我想要的。谢谢。
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)),
   }