【问题标题】:Handling state after fetching data - React获取数据后处理状态 - React
【发布时间】:2017-01-04 15:15:31
【问题描述】:

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

原因是我直接访问了一些参数,{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个photos数组元素就没有问题,唯一的问题是在photos列为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 收到 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}/>
    );
  }
}

减速机:

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

任何其他解决方案将不胜感激。

【问题讨论】:

  • 当你用 [react-redux] 标记它时,我希望在某处看到一个减速器,[react-redux] 标记是否正确?
  • 是的@Icepickle,对此感到抱歉。我刚刚用 reducer 更新了代码。
  • 好吧,那么下一个问题是为什么你不使用连接的组件?
  • @Icepickle 我刚刚再次更新了这个问题,添加了CONNECTOR 你在说什么吗?
  • 您不应该在 componentWillReceiveProps 中设置状态。在 redux 中,状态的唯一来源是 reducer。

标签: javascript reactjs react-redux


【解决方案1】:

为什么不只使用默认道具?

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

【讨论】:

  • Oki,我希望在 componentWillReceiveProps 中处理这个问题,这不是延迟问题,而是如果数组本身在数据库中为空。
  • 这就是我想要的。谢谢。
猜你喜欢
  • 2020-09-19
  • 2020-07-31
  • 2020-12-29
  • 2019-03-10
  • 1970-01-01
  • 2020-10-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多