我正在使用React Native,React Hooks,Redux和Function组件。我正在使用useSelector从Redux从我的状态中获取一个大数组,并使用Flatlist迭代它。在我的平面列表中,我渲染了多个子组件,包括我孩子的子组件。我将主要孩子粘贴在这篇文章的底部。当我在单独的屏幕上并且 FlatList 处于非活动状态并且我的数组trackingBoardList
中的对象内部的属性发生变化时,我希望当我回到屏幕时 Flatlist 会重新呈现,但它没有。此外,即使我尝试使用React.memo()
AvatarListItem
记住子组件,子组件本身也不会重新渲染。我无法重新渲染完整的列表,也无法让子项自己重新渲染。Flatlist 是否与嵌套对象的 React Hooks 和数组不兼容?在我的化简器中,当该数组发生变化时,我确实会不可变地返回该数组,并且我正在使用 Immerdraft
来做到这一点。
我使用 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;
为了回答我自己的问题,我在发布此内容后立即发现了该错误。这是一个可变性问题。我确信我的状态是使用 ImmerJS 不可变的,但是 Immer 没有使用我的draft
状态,而是以某种方式自动使用我的 baseState,它几乎在整个应用程序中无处不在,但最终在这个特定屏幕上引起了问题。如果你有一个非常奇怪的重新渲染问题,无论你做什么,组件都拒绝重新渲染,我强烈建议你专注于你的化简器,并尝试几种不同的方法来返回你的状态。