执行 FLATLIST 时的错误是什么?

What is the error when executing a FLATLIST?

执行时出现以下错误,你知道我做错了什么吗? 我使用了发布的代码

Invariant Violation: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.

Check the render method of FlatListDemo.

This error is located at: in FlatListDemo (at withExpoRoot.js:22) in RootErrorBoundary (at withExpoRoot.js:21) in ExpoRootComponent (at renderApplication.js:34) in RCTView (at View.js:44) in RCTView (at View.js:44) in AppContainer (at renderApplication.js:33)

node_modules\react-native\Libraries\Renderer\oss\ReactNativeRenderer-dev.js:5630:10 in createFiberFromElement node_modules\react-native\Libraries\Renderer\oss\ReactNativeRenderer-dev.js:9710:8 in reconcileSingleElement ... 21 more stack frames from framework internals

import React, { Component } from "react";
import { View, Text, FlatList, ActivityIndicator } from "react-native";
import { List, ListItem, SearchBar } from "react-native-elements";

class FlatListDemo extends Component {
  constructor(props) {
    super(props);

    this.state = {
      loading: false,
      data: [],
      page: 1,
      seed: 1,
      error: null,
      refreshing: false
    };
  }

  componentDidMount() {
    this.makeRemoteRequest();
  }

  makeRemoteRequest = () => {
    const { page, seed } = this.state;
    const url = `https://randomuser.me/api/?seed=${seed}&page=${page}&results=20`;
    this.setState({ loading: true });

    fetch(url)
      .then(res => res.json())
      .then(res => {
        this.setState({
          data: page === 1 ? res.results : [...this.state.data, ...res.results],
          error: res.error || null,
          loading: false,
          refreshing: false
        });
      })
      .catch(error => {
        this.setState({ error, loading: false });
      });
  };

  handleRefresh = () => {
    this.setState(
      {
        page: 1,
        seed: this.state.seed + 1,
        refreshing: true
      },
      () => {
        this.makeRemoteRequest();
      }
    );
  };

  handleLoadMore = () => {
    this.setState(
      {
        page: this.state.page + 1
      },
      () => {
        this.makeRemoteRequest();
      }
    );
  };

  renderSeparator = () => {
    return (
      <View
        style={{
          height: 1,
          width: "86%",
          backgroundColor: "#CED0CE",
          marginLeft: "14%"
        }}
      />
    );
  };

  renderHeader = () => {
    return <SearchBar placeholder="Type Here..." lightTheme round />;
  };

  renderFooter = () => {
    if (!this.state.loading) return null;

    return (
      <View
        style={{
          paddingVertical: 20,
          borderTopWidth: 1,
          borderColor: "#CED0CE"
        }}
      >
        <ActivityIndicator animating size="large" />
      </View>
    );
  };

  render() {
    return (
      <List containerStyle={{ borderTopWidth: 0, borderBottomWidth: 0 }}>
        <FlatList
          data={this.state.data}
          renderItem={({ item }) => (
            <ListItem
              roundAvatar
              title={`${item.name.first} ${item.name.last}`}
              subtitle={item.email}
              avatar={{ uri: item.picture.thumbnail }}
              containerStyle={{ borderBottomWidth: 0 }}
            />
          )}
          keyExtractor={item => item.email}
          ItemSeparatorComponent={this.renderSeparator}
          ListHeaderComponent={this.renderHeader}
          ListFooterComponent={this.renderFooter}
          onRefresh={this.handleRefresh}
          refreshing={this.state.refreshing}
          onEndReached={this.handleLoadMore}
          onEndReachedThreshold={50}
        />
      </List>
    );
  }
}

export default FlatListDemo;

您似乎是在中等水平上学习本教程 https://medium.freecodecamp.org/how-to-build-a-react-native-flatlist-with-realtime-searching-ability-81ad100f6699

遗憾的是,本教程是在 react-native-elements 升级到 v1.0.0 之前编写的。 react-native-elements 升级后,删除了几个组件,并更改了其他组件。有关他们的完整列表,您应该在他们的网站上看到这个 blog post。在这里复制长,但我会重复与您的具体情况相关的部分。

列表

这已被删除,这可能是导致您在尝试导入不再存在的内容时看到的大错误的原因。

https://react-native-training.github.io/react-native-elements/blog/2019/01/27/1.0-release.html#list

List component has been removed! List was just a regular React Native View with some small margin styles. It wasn't actually needed to use the ListItem component. Instead we recommend using the FlatList or SectionList components from React Native which function both as Views and also displaying items, pull to refresh and more.

列表项

roundAvataravatar 已删除,不再使用。

https://react-native-training.github.io/react-native-elements/blog/2019/01/27/1.0-release.html#listitem

avatar, avatarStyle, avatarContainerStyle, roundAvatar, and avatarOverlayContainerStyle removed. Avatars can now be customized using the rightAvatar and leftAvatar props which can either render a custom element or an object that describes the props from Avatar.


解决方案

你有两个选择。

  1. 降级到 v0.19.1
  2. 重构 v1.0.0 的代码

降级

最简单的(虽然这可能行不通,因为与较新版本的 react-native 可能存在兼容性问题)是降级 react-native-elements 的版本。

你可以通过 运行 npm uninstall react-native-elements

然后重新安装特定版本npm install react-native-elements@0.19.1

您可以在此处查看 v0.19.1 组件的完整列表 https://react-native-training.github.io/react-native-elements/docs/0.19.1/overview.html

重构

另一个选择,可能是更好的选择,尽管可以说它需要更多的工作,那就是重构您的代码,以便它使用来自 v1.0.0 的新组件。 您可以在此处查看 v1.0.0 组件的完整列表 https://react-native-training.github.io/react-native-elements/docs/overview.html

正如 Andres 所说,react-native 元素的属性发生了变化,因此我将发布在我的案例中有效的代码。

        import React, { Component } from "react";
    import { View, Platform, Image, Text,  FlatList, ActivityIndicator } from "react-native";
    import { ListItem, List } from "react-native-elements";

    class FlatListDemo extends Component {
      constructor(props) {
        super(props);

        this.state = {
          loading: false,
          data: []
        }
      }

      componentDidMount() {
        this.makeRemoteRequest();
      }

      makeRemoteRequest = () => {
        const url = 'https://randomuser.me/api/?seed=1&page=1&results=20';
        this.setState({ loading: true });

        fetch(url)
          .then(res => res.json())
          .then(res => {
            this.setState({
              data: res.results,
              loading: false,
            });
          });
      };

      render() {
        return (
          <View>

            <FlatList
              data={this.state.data}
              renderItem={({ item }) => (
                <ListItem
                title={
                  <View >
                    <Image style={{height:50}} source={require('./src/img/recarga.jpg')}>
                    </Image>
                    <Text>{item.name}</Text>
                  </View>
                }
                subtitle={item.email}
                />
              )}
              keyExtractor={item=>item.email}
            />
          </View>
        );
      }
    }

    export default FlatListDemo;