【问题标题】:Using Redux and React Hooks, Flatlist will not re-render nor will the individual components inside of it使用 Redux 和 React Hooks,Flatlist 不会重新渲染,其中的单个组件也不会重新渲染
【发布时间】:2019-09-14 00:07:57
【问题描述】:

我正在使用 React Native、React Hooks、Redux 和 Function 组件。我正在使用 useSelector 从 Redux 的状态中获取一个大数组,并使用 Flatlist 对其进行迭代。在我的 Flatlist 中,我渲染了多个子组件,包括我孩子的孩子。我在这篇文章的底部粘贴了主要的孩子。当我在一个单独的屏幕上并且 FlatList 处于非活动状态并且我的数组 trackingBoardList 中的一个对象内部的属性发生变化时,我希望当我回到屏幕时 Flatlist 会重新呈现,但事实并非如此。此外,即使我尝试使用React.memo() 记忆子组件AvatarListItem,子组件本身也不会重新渲染。我无法获得重新渲染的完整列表,也无法让孩子自己重新渲染。 Flatlist 是否与 React Hooks 和数组以及嵌套对象不兼容?在我的减速器中,我确实在该数组更改时不可变地返回该数组,并且我正在使用 Immer draft 进行此操作。

我通过 useSelector 获得我的状态。这是一个包含大量深层嵌套对象的大型数组:

  const trackingBoardList = useSelector((state: iAppState) => {
    return state.trackingBoardAndSchedule.trackingBoardList;
  });

我的平面列表如下所示:

    <FlatList
            data={trackingBoardList}
            extraData={trackingBoardList}
            keyExtractor={() => uuid()}
            renderItem={({ item, index }) => {
              return (
                  <AvatarListItem
                    patientID={item.patient.id}
                    patientFirstName={item.patient.name_first}
                    patientLastName={item.patient.name_last}
                    patientMiddleName={item.patient.name_middle}
                    patientSex={item.patient.gender}
                    patientAge={calculateAge(item.patient.birth_dttm)}
                    visitReason={item.reason_for_visit}
                    time={item.created_dttm}
                    inProgress={false}
                    patientAvatarURI={item.patient.profile_image_name}
                    status={item.evisit_status}
                  />
              );
            }}
          />

我的子组件如下所示:

const AvatarListItem = (props: iAvatarListItem) => {
  return (
    <>
      <ListItemContainer {...props}>
        <Avatar
          avatarSize={42}
          avatarType='patient'
          avatarUserID={props.patientID}
          avatarURI={props.patientAvatarURI}
        />
        <NameAgeColumn>
          <ColumnTitle>
            {props.patientFirstName}
            {props.patientMiddleName ? ` ${props.patientMiddleName}` : ''}
            {` ${props.patientLastName}`}
          </ColumnTitle>
          <ColumnSmallText>
            {props.patientSex === 'M' ? 'Male, ' : ''}
            {props.patientSex === 'F' ? 'Female, ' : ''}
            {props.patientAge} Years
          </ColumnSmallText>
        </NameAgeColumn>
        <ReasonColumn>
          <ColumnTitle>Reason</ColumnTitle>
          <ColumnSmallText>{props.visitReason}</ColumnSmallText>
        </ReasonColumn>
        <LongBadge>
          <LongBadgeText>{props.status}</LongBadgeText>
        </LongBadge>
      </ListItemContainer>
    </>
  );
};

export default AvatarListItem;

【问题讨论】:

  • 您在Flatlist? 中实际在哪里使用 trackingBoardList 以及您如何/在哪里调度更改状态的操作?
  • 嗨@RutherfordWonkington 我在下面发现了我的错误,但为了回答您的问题,当数组作为data 提供给Flatlist 时,它会迭代该数据。因此,trackingBoardList 中的每个对象都是item,每次迭代都与循环相同。

标签: reactjs react-native redux react-hooks react-native-flatlist


【解决方案1】:

为了回答我自己的问题,我在发布后立即发现了这个错误。这是一个可变性问题。我确信我的状态使用 ImmerJS 是不可变的,但是 Immer 没有使用我的 draft 状态,而是以某种方式自动使用我的 baseState,它几乎在整个应用程序的任何地方都有效,但最终在这个特定的屏幕上引起了问题。如果您遇到一个非常奇怪的重新渲染问题,即无论您做什么,组件都拒绝重新渲染,我强烈建议您专注于您的减速器并尝试几种不同的方式来返回您的状态。

【讨论】:

    猜你喜欢
    • 2023-03-28
    • 1970-01-01
    • 2023-03-13
    • 2017-12-29
    • 2020-02-18
    • 1970-01-01
    • 2020-02-05
    • 1970-01-01
    • 2016-05-09
    相关资源
    最近更新 更多