react-native:使用asState / await和setState

问题描述 投票:1回答:2

我有这个简单的代码。

export default class ProductDetail extends Component {

  constructor(props) {
    super(props);
    this.state = { test: null,id:this.props.navigation.state.params.productId };
    console.log(1);
  }

  componentWillMount() {
    console.log(2);
    this.getProductRequest(this.state.id);
    console.log(3);
  }

  async getProductRequest(id) {
    try {
      let api_token = await AsyncStorage.getItem('apiToken')
      let response = await fetch('...')
      let json = await response.json();
      this.setState({test: json});

    } catch(error) {
      //
    }

  }

  render() {
    console.log(4);
    console.log(this.state.test);
    return (
      <View><Text>test</Text></View>
    );
  }
}

现在,我在调试器中检查了它:

我期待这个结果:

1

2

3

4

{data:{...},状态:“成功”,...}

但我明白了:

1

2

3

4

空值

4

{data:{...},状态:“成功”,...}

我认为这意味着render()运行两次!

我该如何处理这个错误?

json reactjs react-native async-await
2个回答
4
投票

我认为这意味着render()运行两次!

它确实:在您的异步结果可用之前,然后再次使用它并使用setState。这是正常的和预期的。

您无法阻止第一个渲染等待异步操作完成。你的选择是:

  1. 如果组件还没有数据,请正确呈现组件。要么,
  2. 如果您不希望在异步操作完成之前渲染组件,请将该操作移至父组件,并仅在数据可用时呈现此组件,并将数据作为props传递给此组件。

1
投票

只是为了补充T.J Crowder的答案,我喜欢做的一件事是如果还没有收到数据,则返回ActivityIndicator

import {
    View,
    Text,
    ActivityIndicator
} from 'react-native';

export default class ProductDetail extends Component {
    ... your code ...

    render() {
        if (!this.state.test) {
            return <ActivityIndicator size='large' color='black' />
        }

        console.log(4);
        console.log(this.state.test);
        return (
          <View><Text>test</Text></View>
        );
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.