当屏幕渲染时反应本机redux道具没有更新

时间:2019-05-19 18:04:01

标签: reactjs react-redux react-native-android

我没有在此处添加reducer和action,因为那很好,可以从服务器获取banner objects。 这里的问题是当我在渲染中执行console.log(this.props.banner_list)时。似乎两次调用render方法并且第一次调用this.props.banner_list时,它是未定义的,并且当我尝试在视图中显示对象时会抛出错误。第二次当它在this.props.banner_list中正确显示console时。我不明白这里发生了什么。有人请帮助我

class App extends Component<Props> {

    componentDidMount(){
       this.props.getBanners()
    }
  render() {
    console.log(this.props)// here iam logging the props

    return (
      <View style={styles.container}>
       // its throwing error so i comment it , i can see the render 
       // getting called two times. first time its undefined .
        {banner_list.banners.banners.map(obj=>{
          return(
            <Text>{obj.title}</Text>
          )
        })}  

      </View>
    );
  }


function mapStateToProps(state){
      return {
        banners_list:state.banners
      }   
    }

    function mapDispatchToProps(dispatch){
        return bindActionCreators({getBanners}, dispatch)
    }

3 个答案:

答案 0 :(得分:2)

关于“渲染方法似乎被调用了两次” :正确,它被调用了两次。挂载组件后,将调用render()。这会触发componentDidMount()被呼叫。调用componentDidMount()时,它将像您的代码中那样调用this.props.getBanners()。这会触发重新渲染,第二次调用render()

重新“第一次未定义this.props.banner_list” 正确。如上所述,第一次渲染发生在调用componentDidMount()之前,因此发生在调用this.props.getBanners()之前。此时,this.props存在,因此不会引发错误,但是它尚未包含banners字段,因此它仅返回undefined

关于“当我尝试在视图内部显示对象时会抛出错误” 的原因是,如果尝试在视图内部呈现未定义的对象,则会抛出错误。在此初始渲染期间,this.props.banners未定义,因此会出现错误。

解决方案是有条件地渲染视图。如果您执行<View>{a && b}</View>,如果a为假,那么Javascript会自动将其呈现为<View>null</View>,而无需检查b是什么。因此,请按照以下方式重新编写代码:

class App extends Component<Props> {

    componentDidMount(){
       this.props.getBanners()
    }
  render() {
    console.log(this.props)// here iam logging the props

    return (
      <View style={styles.container}>
       // its throwing error so i comment it , i can see the render 
       // getting called two times. first time its undefined .
        {banner_list.banners && banner_list.banners.banners.map(obj=>{
          return(
            <Text>{obj.title}</Text>
          )
        })}  

      </View>
    );
  }


function mapStateToProps(state){
      return {
        banners_list:state.banners
      }   
    }

    function mapDispatchToProps(dispatch){
        return bindActionCreators({getBanners}, dispatch)
    }

我在其中添加的所有^^是banner_list.banners &&之前的banner_list.banners.banners.map

答案 1 :(得分:1)

  render() {
    console.log(this.props)// here iam logging the props

    return (
      <View style={styles.container}>
       // its throwing error so i comment it , i can see the render 
       // getting called two times. first time its undefined .
        {banner_list.banner && banner_list.banners.banners.map(obj=>{
          return(
            <Text>{obj.title}</Text>
          )
        })}  

      </View>
    );
  }

您可以更改该行代码。也许正在发生的事情是您状态的开始,我想象您的redux状态首先是这样的

{
    banners:{}
}

以及

之后
{
    banners:{
        banners:{
            banners:[
            {title:'Hello world'}
            ]
        }
    }
}

问题在于,每当您尝试获取未定义的属性时,都会返回错误,因此一开始,您可以要求该属性。

答案 2 :(得分:1)

正在发生的事情是,当App组件首次呈现时,您的redux存储状态banners可能未定义。组件安装后,调用this.props.getBanners将基本上触发对redux存储的更新,这将依次向App组件分发新的道具。

当组件收到新的道具时,它将根据从redux商店收到的道具重新渲染。

因此,在尝试访问banners_list.banners.banners.map时,由于banners_list为空,因此在第一个渲染上将返回错误。为了减轻这种情况,您需要在渲染方法中添加一个检查,像这样...

render() {
  const { banners_list } = this.props;

  return (
    <View style={styles.container}>
      { 
        banners_list &&
          banners_list.banners.banners.map(obj=> (<Text>{obj.title}</Text>))
      }  
    </View>
  );
}