首页 > 解决方案 > 在反应中将axios响应传递给子组件

问题描述

我正在开发一个实时搜索应用程序。我有 3 个组件。搜索、搜索栏和搜索结果。在 SearchBar 内的每次输入更改时,都会执行一个事件处理程序。此函数从 Search 传递到 SearchBar。每次更改时,父组件都会向服务器发送请求并获取数据。然后,父母将它们传递给它的孩子,SearchResults 和 SearchResults 呈现它们。但问题是子组件总是落后一步

例如,我输入了 sam。搜索将 sam 发送到服务器并收到响应。然后将它们传递给 SearchResults。但现在如果我输入另一个 s char,它会呈现关于“sa”而不是“sam”的响应,我们在搜索栏中有 sams,但 SearchResults 呈现有关“sam”的获取数据。

class Search extends Component {
constructor() {
    super();
    this.http = new Http();
    this.state = {phrase: ''};
    this.searchRes = null;
}

componentDidUpdate() {
    console.log('Search updated')
}

handleChange = async e => {
    await this.setState({
        phrase: e.target.value
    });
    console.log('state: '+this.state.phrase);
    this.sendPhrase();
};

sendPhrase() {
    return this.http.post('v1/search', {'phrase': this.state.phrase})
        .then(response =>
            this.searchRes = <SearchResults searchRes={response.data}/>
        );
}

render() {
    return (
        <>
            <Col xs={12}>
                <SearchBar handleChange={this.handleChange} phrase={this.state.phrase}/>
            </Col>
            <Col xs={12}>
                {this.searchRes}
            </Col>
        </>
    );
}
}

我提前感谢您的关注:)

标签: javascriptreactjsasynchronousaxios

解决方案


如果你想让一个组件重新渲染,你需要设置状态。像这样的行不会导致组件重新渲染:

this.searchRes = <SearchResults searchRes={response.data}/>

您设置状态的唯一时间是发生更改时,此时, this.searchRes 设置为您将其设置为最后一次搜索完成的任何内容。所以你总是会在最后一次渲染它。

解决方法是将结果移动到状态:

constructor(props) {
  super(props);
  this.http = new Http();
  this.state = {
    phrase: '',
    results: null
  };
}

//...

sendPhrase() {
    return this.http.post('v1/search', {'phrase': this.state.phrase})
        .then(response => 
            this.setState({ results: response.data })
        );
}

render() {
    return (
        <>
            <Col xs={12}>
                <SearchBar handleChange={this.handleChange} phrase={this.state.phrase}/>
            </Col>
            <Col xs={12}>
                {this.state.results && (
                    <SearchResults searchRes={this.state.results}/>
                )}
            </Col>
        </>
    );
}

推荐阅读