代码之家  ›  专栏  ›  技术社区  ›  Steve Waters

React:布尔变量,用于指示渲染前的成功获取

  •  2
  • Steve Waters  · 技术社区  · 7 年前

    我想使用一个布尔变量,使渲染仅在两个不同的获取都完成后才可能进行。我对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
        });
        }
      }
    
    }
    

    然后,我在render方法中进行了以下条件渲染:

    {(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
    }
    

    否则渲染效果很好,但问题是,渲染发生在第二次提取之前,而渲染已经发生。 所以我现在试图阻止使用一些布尔值进行渲染。这是不起作用的部分。

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

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

    这只是为了表明我想做什么:

    成功完成提取后,将布尔值hasSearchedPersons和Hassearchedprojects设置为true。

    然后,当这两个都完成时,状态中的布尔hasSearched将设置为true,并且渲染将在两个提取都完成的情况下进行。

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

    1 回复  |  直到 7 年前
        1
  •  3
  •   The Reason    7 年前

    只是几条关于 setState . 从…起 react 文档:

    setState()将更改排入组件状态队列并告知React 此组件及其子组件需要使用 已更新状态。

    这意味着在你改变状态的时候 设置状态 重新渲染组件。设置之前 hasSearch true 渲染组件两次。因此,为了避免不必要的重复,您应该在 fetch es已完成。这是可能的 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 })
      })
    

    希望这会有所帮助。