javascript - react : Boolean variables to indicate a successful fetch before rendering

标签 javascript reactjs asynchronous promise fetch-api

我想使用 bool 变量来使渲染仅在两次不同的提取都完成后才可能进行。我对 React 和 JavaScript 都很陌生,所以请耐心等待......

问题:

我的代码的相关部分:

class AddressBook extends Component {

  constructor() {
    super();
    this.state = {
      personData: [],
      projectData: [],
      hasSearched: false,
      simplePersonUrl: 'path-to-api/persons',
      simpleProjectUrl: 'path-to-api/projects',
    }
  }

  addressBookSearch(value) {
    var hasSearchedPersons = false;
    var hasSearchedProjects = false;

    if (value !== '' && value.length > 2) {
      const urlsToUse = this.apiUrlsToUse();

      fetch(`${urlsToUse["personUrl"]}${value}`)
        .then((response) => response.json()).then((responseJson) => {
        this.setState({personData: responseJson}).then(() => this.hasSearchedPersons = true)
      })

      fetch(`${urlsToUse["projectUrl"]}${value}`)
        .then((response) => response.json()).then((responseJson) => {
        this.setState({projectData: responseJson}).then(() => this.hasSearchedProjects = true)
      })
    }

    if (hasSearchedPersons == true && hasSearchedProjects == true) {
      this.setState({
        hasSearched: true
    });
    }
  }

}

然后我在渲染方法中有这个条件渲染:

{(this.state.hasSearched && (this.state.personData.length > 0 || this.state.projectData.length > 0)) &&
      <div>
        <Paper style={{boxShadow: 'none'}}>
          <SearchResultTab personData={this.state.personData} projectData={this.state.projectData}/>
        </Paper>
      </div>
}

{(this.state.hasSearched && this.state.personData.length <= 0 && this.state.projectData.length <= 0)
      ? <div style={{textAlign: 'center'}}>No results..</div>
      : null
}

否则渲染效果很好,但问题是当渲染已经发生时,渲染会在第二次获取未完成之前发生。 所以我现在尝试阻止使用一些 bool 值进行渲染。这是不起作用的部分。

现在,我知道 promise 的最后一部分是错误的,因为它给了我:

Uncaught (in promise) TypeError: Cannot read property 'then' of undefined

它只是表明我想做什么:

当获取成功完成时,将 bool 值 h​​asSearchedPersons 和 hasSearchedProjects 设置为 true。

然后,当这两者都完成时,状态中的 bool 值 h​​asSearched 将设置为 true,并且渲染将在完成两次提取后发生。

如何做到这一点?我的头快要爆炸了。谢谢。

最佳答案

关于setState的一些注释。来自 react文档:

setState() enqueues changes to the component state and tells React that this component and its children need to be re-rendered with the updated state.

这意味着每次您更改状态时,都可以使用 setState 重新渲染组件。在将 hasSearch 设置为 true 之前,您重新渲染了组件两次。因此,为了避免不必要的重新渲染,您应该在 fetch 完成后使用它一次。这可以通过 Promise.all() (已在评论中提到)实现。

Promise.all([
  fetch(`${urlsToUse["personUrl"]}${value}`),
  fetch(`${urlsToUse["projectUrl"]}${value}`)
]).then(responses => Promise.all(responses.map(res => res.json())
  .then(values => {
    // doing something with it.
    // once you are done use setState
    this.setState({ hasSearched: true })
  })

希望能有所帮助。

关于javascript - react : Boolean variables to indicate a successful fetch before rendering,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48156655/

相关文章:

arrays - 如何在 Swift 中等待函数执行直到 json 加载?

javascript - MEAN 堆栈路由问题, Angular 路由不起作用

javascript - Node.js 中所有内置事件的列表?

javascript - 算法运行时间 Hackerrank 插入排序问题

javascript - 带过滤器的 React JS 表

javascript - 基于 JSON 数据的 React JS 动画

java - 在异步 servlet 中用新请求替换旧请求

javascript - 麻糬游戏集成问题

reactjs - 缩小/优化 NextJS 站点

javascript - Angular 5 karma 单元测试 : Failed: Cannot read property childcomponent property ( itgroup) of undefined