Javascript React Native async Array.map=未定义不是对象

Javascript React Native async Array.map=未定义不是对象,javascript,react-native,async-await,Javascript,React Native,Async Await,我尝试用ReactNative创建我的第一个混合应用程序。我的数组有问题。映射 class HomeScreen extends React.Component { state = { isLoading: false, captured: false, wished: false, exchanged: false, data: {} }; async getPokemonFromApiAsync() { try {

我尝试用ReactNative创建我的第一个混合应用程序。我的数组有问题。映射

class HomeScreen extends React.Component {

  state = {
    isLoading: false,
    captured: false,
    wished: false,
    exchanged: false,
    data: {}
  };

  async getPokemonFromApiAsync() {
    try {
      this.setState({isLoading: true});
      let response = await fetch('https://pokeapi.co/api/v2/pokemon/?limit=0&offset=20');
return this.setState({
        isLoading: false,
        data: await response.json()
       });
    } catch (error) {
      console.error(error);
  }

  (...)    

  componentWillMount() {
      this.getPokemonFromApiAsync()
  }

  (...)

  result = (result = this.state.data.results) => {
      console.log('test', this.state.data);
      return (
         <View>

             (...)

             result.map( (item, index) => {

             (...)

             }
         </View>
      )
  } 
}
控制台中有许多错误:

警告:无法对尚未安装的组件调用%s。这是一个no-op,但它可能表示应用程序中存在错误。相反,直接分配给
this.state
,或者定义一个
state={}在%s组件、设置状态、主屏幕中具有所需状态的类属性

对我来说,这很正常


异步Http请求的良好生命周期是什么?

使用axios库github的最佳方式


最后,每周下载量超过4000000+Github启动50000+

更好的方法是在您的承诺通过“then”解决时实现您的状态值

let response=fetch('https://pokeapi.co/api/v2/pokemon/?limit=0&offset=20')
。然后((响应)=>{
这是我的国家({
孤岛加载:false,
数据:response.json()
});
});
也许您可以在Promise回调中处理数据(
result.map
),并直接将结果插入组件中


顺便说一句,XHR调用通常在
componentDidMount
方法中处理。

您的错误是由您如何将初始
数据设置为状态引起的

您已将其设置为:

state = {
  isLoading: false,
  captured: false,
  wished: false,
  exchanged: false,
  data: {} // <- here you define it as an object, with no parameters
};
这是因为在初始渲染时,在回传fetch响应之前,它正在尝试映射不存在的
this.state.data.results
。您需要确保状态中存在
结果的初始值

这将停止初始错误,但是您必须确保为
数据
保存到状态的也是一个数组,否则您将继续得到相同的错误


componentWillMount
已被弃用,您应该使用
componentDidMount

另外,当您在
componentWillMount
内部调用异步函数时,您应该按照以下方式对其进行重构:

async componentDidMount() {
  await this.getPokemonFromApiAsync()
}
因此,在完成获取请求之前不会进行装载


我还将重构您的
getpokemonfrompiasync
,以便在尝试将其设置为状态之前获得
response.json()
。您也不需要return语句,因为
this.setState
不返回任何内容

async getPokemonFromApiAsync() {
  try {
    this.setState({isLoading: true});
    let response = await fetch('https://pokeapi.co/api/v2/pokemon/?limit=0&offset=20');
    let data = await response.json(); // get the data 
    this.setState({
      isLoading: false,
      data: data // now set it to state
    });
  } catch (error) {
    console.error(error);
}

小吃: 下面是一个非常简单的小吃,展示了代码的工作原理

零食代码:

export default class App extends React.Component {

  state = {
    isLoading: false,
    captured: false,
    wished: false,
    exchanged: false,
    data: { results: [] } // <- here you should define the results inside the object
  };

  getPokemonFromApiAsync = async () => {
    try {
      this.setState({ isLoading: true });
      let response = await fetch('https://pokeapi.co/api/v2/pokemon/?limit=0&offset=20');
      let data = await response.json(); // get the data
      this.setState({
        isLoading: false,
        data: data // now set it to state
      });
    } catch (error) {
      console.error(error);
    }
  }

  async componentDidMount () {
    await this.getPokemonFromApiAsync();
  }

  render () {
    return (
      <View style={styles.container}>
        {this.state.data.results.map(item => <Text>{item.name}</Text>)}
      </View>
    );
  }
}
导出默认类App扩展React.Component{
状态={
孤岛加载:false,
抓获:假,,
希望:错,
交换:错,
数据:{results:[]}//{
试一试{
this.setState({isLoading:true});
let response=等待取数('https://pokeapi.co/api/v2/pokemon/?limit=0&offset=20');
let data=wait response.json();//获取数据
这是我的国家({
孤岛加载:false,
data:data//现在将其设置为state
});
}捕获(错误){
控制台错误(error);
}
}
异步组件didmount(){
等待这个消息;
}
渲染(){
返回(
{this.state.data.results.map(item=>{item.name})}
);
}
}

获取错误的原因
TypeError:Undefined不是对象(评估'result.map')
是从
this.state.data.results
获取
结果,但由于数据是异步的,在第一次呈现时,数据是
{}
(因为您将其设置为状态)因此,
data.result
未定义的
,您不能在未定义的数据库中使用
.map()

要解决此问题,可以在渲染前检查
data.result
是否未定义

  return (
     <View>

         (...)

         result && result.map( (item, index) => {

         (...)

         }
     </View>
  )
返回(
(...)
result&&result.map((项目、索引)=>{
(...)
}
)

Drop wait in the state,您会很好的。谢谢。但是我有相同的错误。console.log('test',this.state.data)返回对象{}。我的问题是数据是检索,但不是在状态下检索。嗯,您的fetch语句中缺少配置对象。请确保您提供了配置对象。我怀疑您的fetch失败。您好,future的访问者,有关详细信息:
async componentDidMount() {
  await this.getPokemonFromApiAsync()
}
async getPokemonFromApiAsync() {
  try {
    this.setState({isLoading: true});
    let response = await fetch('https://pokeapi.co/api/v2/pokemon/?limit=0&offset=20');
    let data = await response.json(); // get the data 
    this.setState({
      isLoading: false,
      data: data // now set it to state
    });
  } catch (error) {
    console.error(error);
}
export default class App extends React.Component {

  state = {
    isLoading: false,
    captured: false,
    wished: false,
    exchanged: false,
    data: { results: [] } // <- here you should define the results inside the object
  };

  getPokemonFromApiAsync = async () => {
    try {
      this.setState({ isLoading: true });
      let response = await fetch('https://pokeapi.co/api/v2/pokemon/?limit=0&offset=20');
      let data = await response.json(); // get the data
      this.setState({
        isLoading: false,
        data: data // now set it to state
      });
    } catch (error) {
      console.error(error);
    }
  }

  async componentDidMount () {
    await this.getPokemonFromApiAsync();
  }

  render () {
    return (
      <View style={styles.container}>
        {this.state.data.results.map(item => <Text>{item.name}</Text>)}
      </View>
    );
  }
}
  return (
     <View>

         (...)

         result && result.map( (item, index) => {

         (...)

         }
     </View>
  )