简体   繁体   English

使用Redux和React Hooks,Flatlist既不会重新渲染,也不会重新渲染其中的各个组件

[英]Using Redux and React Hooks, Flatlist will not re-render nor will the individual components inside of it

I'm using React Native, React Hooks, Redux and Function components. 我正在使用React Native,React Hooks,Redux和Function组件。 I am using useSelector to get a large array from my state from Redux and I iterate through it using a Flatlist. 我正在使用useSelector从Redux的状态中获取大型数组,并使用Flatlist对其进行迭代。 In my Flatlist I render multiple child components, including children of my child. 在我的平面清单中,我渲染了多个子组件,包括我孩子的子组件。 I pasted the main child at the bottom of this post. 我在该帖子的底部粘贴了主要孩子。 When I am on a separate screen and the FlatList is inactive and a property changes inside of an object in my array trackingBoardList , I expect that Flatlist will rerender when I come back to the screen, but it doesn't. 当我在单独的屏幕上并且FlatList处于非活动状态并且属性在数组trackingBoardList中的对象内部更改时,我希望Flatlist在返回屏幕时会重新呈现,但事实并非如此。 Furthermore, even if I try to memoize the child component AvatarListItem using React.memo() , the child by itself also will also not re-render. 此外,即使我尝试使用React.memo() AvatarListItem子组件AvatarListItem ,子组件本身也不会重新渲染。 I cannot get the full list to re-render, nor can I get the children by themselves to re-render. 我无法获得重新渲染的完整列表,也无法独自让孩子们重新渲染。 Is Flatlist incompatible with React Hooks and arrays, with nested objects? Flatlist是否与React Hooks和带有嵌套对象的数组不兼容? In my reducer I am indeed returning that array immutably when it changes, and I'm doing that using Immer draft . 在我的reducer中,当数组改变时,我确实不可变地返回了该数组,而我正在使用Immer draft这样做。

I get my state with useSelector. 我通过useSelector获得状态。 It's a large array with lots of deep nested objects: 这是一个包含许多深层嵌套对象的大型数组:

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

My Flatlist looks like this: 我的平面清单如下所示:

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

My child component looks like this: 我的子组件如下所示:

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;

To answer my own problem, I discovered the bug immediately after I posted this. 为了回答我自己的问题,我在发布此消息后立即发现了该错误。 It was a mutability issue. 这是一个可变性问题。 I was assured that my state was immutable using ImmerJS however instead of using my draft state Immer was somehow automajically using my baseState, which worked almost everywhere throughout the app but finally caused an issue on this particular screen. 我确信使用ImmerJS是不会改变我的状态的,但是不是使用draft状态,而是使用Immer自动地使用了baseState,该状态在整个应用程序中几乎都适用,但最终在此特定屏幕上引起了问题。 If you are having a very strange re-rendering issue where a component just refuses to re-render no matter what you do, I highly recommend focusing on your reducer and trying a few different ways of returning your state. 如果您遇到一个非常奇怪的重新渲染问题,无论您做什么,组件都拒绝重新渲染,我强烈建议您专注于您的reducer并尝试几种不同的返回状态的方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM