更新数据时(Redux)React Native FlatList不呈现

时间:2018-09-04 21:18:13

标签: reactjs react-native redux

我有一个问题,我的FlatList无法呈现我要的项目。我用来渲染列表的数据可以从我的Redux存储中成功获得,并且我正在将我的FlatList渲染到的同一组件的componentDidMount中存储该存储。我注意到该组件两次点击了render方法在需要将数据提供给renderItem属性时,似乎仍然没有数据。

我在CardBuilder中放入了一个调试器,并注意到它第一次在每个项目中都被命中一次,但是由于this.props.picskit是未定义的,因此不会渲染。即使在父元素中picskitz已在商店中被水化并可以访问,它也不会再被击中。我怎样才能让我的FlatList尝试再次使用原始数据源进行渲染?我最终想为此添加无限滚动,但是现在我只是想让前25个值(单个页面)至少呈现。任何帮助,不胜感激。

这是我的componentDidMount:

componentDidMount(){
    const { dispatch, user, token, history } = this.props
    const { pageNumber } = this.state
    const LOGIN = 'LOGIN'
    if ( token && user ){
      dispatch({ type: LOGIN, user: {user, token} })
      dispatch(getAllPicskitz(pageNumber, token, history))
    } else {
        dispatch(getAllPicskitz(pageNumber, user.token, history))
    }
  }

这是我的FlatList:

 keyExtractor = ( picskit, index) => picskit.id.toString()

  render(){
    const { picskitz } = this.props

    return(
      <View style={styles.container}>
        <View style={styles.headerContainer}>
          <Image
            source={ require('../media/logo-with-color.png')}
          />
        </View>
        <FlatList
          data={picskitz}
          renderItem={ ({picskit}) => <CardBuilder picskit={picskit} /> }
          keyExtractor={this.keyExtractor}
        />
        <LowerNavBar />
      </View>
    )
  }

最后,这是我要渲染的“ CardBuilder”组件:

  render(){
    const {picskit} = this.props
      if ( picskit !== undefined ){
        return (
          <View style={styles.container}>
            <View style={styles.headerContainer}>
              <View style={styles.titleContainer}>
                <Text style={styles.titleText}> {picskit.title} </Text>
              </View>
              <View style={styles.detailsContainer}>
                <View style={styles.viewsContainer}>
                  <Image
                    source={ require('../media/icon-glasses.png')}
                  />
                  <Text> {picskit.views} </Text>
                </View>
                <Text style={styles.detailsText}> {picskit.owner.name} </Text>
              </View>
            </View>

            <ImageBackground 
              source={{uri: JSON.parse(picskit.content)[0].aws_url}} 
              style={styles.mainImage}
              >
              <Image 
                source={ require('../media/frame-black.png')}
                style={{width: '100%', height: '100%'}} 
              />
            </ImageBackground>
          </View>
        )
      }
    return null
  } 
}

3 个答案:

答案 0 :(得分:1)

您忘记将extraData属性传递给FlatList

extraData={picskitz}

这是告诉FlatList如果{picskitz}值更改的情况下重新呈现

答案 1 :(得分:0)

我找到了一个可能的答案,但是我不确定这是否是最有效或最正确的方法。首先,我添加了一些条件逻辑以仅在我有数据的情况下才呈现FlatList。看起来像这样:

{ picskitz ?
    <FlatList
        data={picskitz}
        renderItem={ ({item}) => <CardBuilder item={item} /> }
        keyExtractor={(x, i) => i.toString() }
        onEndReached={this.loadMore}
    />
  :
    null
}

此外,在更深入地看一下React Native FlatList文档时,发现有一个内置的prop。处理我写的这种条件逻辑。此道具可让您在dataSource / list为空时呈现另一个组件或执行功能。这是我更新后的FlatList组件的样子,其中已删除了条件。我的f => f基本上意味着:什么也不做。

  <FlatList
    data={picskitz}
    renderItem={ ({item}) => <CardBuilder item={item} /> }
    listEmptyComponent={ f => f }
    keyExtractor={(x, i) => i.toString() }
    onEndReached={this.loadMore}
  />

接下来要做的是调整loadMore函数以异步运行。看起来像这样:

  loadMore = () => {
    const { dispatch, user, history } = this.props
    this.setState( 
      state => ({ pageNumber: state.pageNumber + 1 }), async () => 
        await dispatch(getMorePicskitz(this.state.pageNumber, user.token, history))
    )
  }

您会注意到调度正在等待,请确保在再次调用render()之前数据已正确存储在存储中,这意味着FlatList现在将包含50个完整列表(来自之前加载的25个)呈现CardBuilder组件。

如果有人有建议,我很愿意接受建议!

答案 2 :(得分:0)

如果Flatlist的数据属性发生更改,则它将自动重新呈现。这意味着您的数据没有成功地从Redux存储传递到组件。无论您从存储中获取数据并将其作为道具传递的任何地方,我都将开始仔细检查代码和调试。