如何通过 FlatList 渲染组件?

How to render component via FlatList?

将 React Native 与 TypeScript 和 Redux 工具包结合使用

您好,我正在为通过 FlatList 呈现消息列表而烦恼。通过 ScrollView,一切都呈现良好,但我需要实施 infiniti 滚动。所以我正在做这样的事情

const MessagesScreen = () => {
  const companyId = useAppSelector(getCompanyId);
  const userId = useAppSelector(getUserId);

  const {
    data: messages,
    isLoading,
    refetch
  } = useGetMessagesQuery({ userId, companyId });
  useFocusEffect(refetch);

  return (
    <FlatList
      data={messages}
      renderItem={() => {
        <Messages messages={messages} />;
      }}
    />
  );
};

return() 中,我正在尝试使用此处的组件消息渲染 FlatList:

const Messages = ({ messages }: { messages: Message[] }) => {
  const navigation =
    useNavigation<RootStackScreenProps<'DrawerNavigator'>['navigation']>();
  const { colors } = useTheme();

  return (
    <View style={styles.container}>
      {messages.map(message => {
        const createdAt = message.created_at;
        const isRead = message.read;
        const icon = isRead ? 'email-open-outline' : 'email-outline';
        const onClick = () => {
          navigation.navigate('Message', {
            messageId: message.id
          });
        };

        return (
          <TouchableOpacity key={message.id} onPress={onClick}>
            <View
              style={[styles.message, { borderBottomColor: colors.separator }]}
            >
              <View style={styles.iconPart}>
                <Icon
                  name={icon}
                  type="material-community"
                  style={
                    isRead
                      ? { color: colors.separator }
                      : { color: colors.inputFocus }
                  }
                  size={24}
                ></Icon>
              </View>
              <View style={styles.bodyPart}>
                <Text
                  numberOfLines={1}
                  style={[isRead ? styles.readSubject : styles.unReadSubject]}
                >
                  {message.subject}
                </Text>
                <Text
                  numberOfLines={1}
                  style={[isRead ? styles.readBody : styles.unReadBody]}
                >
                  {message.body}
                </Text>
              </View>
              <View style={styles.datePart}>
                <Text style={{ color: colors.shadow }}>
                  {dayjs(createdAt).fromNow()}
                </Text>
              </View>
            </View>
          </TouchableOpacity>
        );
      })}
    </View>
  );
};

实际上行为只是呈现错误的白屏

Possible Unhandled Promise Rejection (id: 17):
Error: Objects are not valid as a React child (found: object with keys {id, msg_type, created_at, subject, body, author, company_id, read}). If you meant to render a collection of children, use an array instead.

你的回调函数有问题: 您没有 returning 消息组件

1:去掉大括号

 return (
    <FlatList
      data={messages}
      renderItem={() => <Messages messages={messages}/> }
    />
  );

2:添加return语句

 return (
    <FlatList
      data={messages}
      renderItem={() => {
       return <Messages messages={messages} />;
      }}
    />
  );

两件事:

您错误地使用了 renderItem 回调:

<FlatList
      data={messages}
      renderItem={() => {
      // ^ ignoring the renderItem props
        return <Messages messages={messages} />;
      }}
    />

在这里,对于消息数组中的每个项目,您正在呈现一个组件并将所有 消息传递给它。所以你会得到重复的元素。

传递 renderItem 回调 {item, index} 其中 item 是数组中的当前项(index 是数组的索引)

在此处查看文档: https://reactnative.dev/docs/flatlist

通常情况是 renderItem 回调一次呈现一个项目,如下所示:

<FlatList
      data={messages}
      renderItem={({item}) => {
        return <Message message={item} />;
      }}
    />

例如我会制作一个仅呈现一项的 <Message/> 组件。