首页 > 解决方案 > handleChange 中对象数组的 setState 不起作用

问题描述

我使用 elasticsearch 在我的视图中进行搜索(ReactJs)。我创建了一个函数 handleChange 来根据我正在搜索的内容更改表中数据的状态。所以到目前为止我在我的代码中这样做了:

var esClient = new elasticsearch.Client({
  host: 'localhost:9200',
  log: 'info'
});

class MesExtraits extends Component {

  constructor() {
    super();
    this.state = {
      MP3info: [],
      searchText: '',
    }
  }

  updateSearch = (evt) => {
    this.setState({ searchText: evt.target.value, });
    var searchQ = evt.target.value;
    var search_queryES = "titre:" + searchQ + "*"

    esClient.search({
      q: search_queryES
    }).then(function (body) {
      this.setState({ MP3info: body.hits.hits.map(i => i._source) })

      console.log(this.state.MP3info)

      console.log(body.hits.hits.map(i => i._source))

    }.bind(this), function (error) {
      console.trace(error.message);
    });
  };

  render() {

    const { MP3info } = this.state;
    return (

      <div>
        <SearchBox styleName="gx-d-none gx-d-lg-block gx-lt-icon-search-bar-lg"
          placeholder="Search in app..."
          onChange={this.updateSearch.bind(this)}
          value={this.state.searchText}
        />
        <Paper className={classes.root}>
          <Table className={classes.table} aria-label="simple table">
            <TableHead>
              <TableRow>
                <TableCell><IntlMessages id="MP3.titre" /></TableCell>
                <TableCell align="left"><IntlMessages id="MP3.descfiption" /></TableCell>
                <TableCell align="left"><IntlMessages id="MP3.langue" /></TableCell>
                <TableCell align="left"><IntlMessages id="MP3.stats" /></TableCell>
              </TableRow>
            </TableHead>
            <TableBody>
              {MP3info.map(row => (
                <TableRow key={row.titre}>
                  <TableCell component="th" scope="row">
                    {row.titre}
                  </TableCell>
                  <TableCell align="left">{row.description}</TableCell>
                  <TableCell align="left">{row.langue}</TableCell>
                  <TableCell align="left"> <span id={row.idMedia} onClick={this.onClickPoup}><i class="icon icon-chart" /> </span> </TableCell>
                </TableRow>
              ))}
            </TableBody>
          </Table>
        </Paper>
      </div>
    );
  }
}

问题是当我console.log(this.state.MP3info)在 setState for MP3info 之后它没有改变。任何帮助,将不胜感激。

标签: arraysreactjselasticsearchsearchstate

解决方案


setState是异步的。所以它会像这样工作:

this.setState({ MP3info: body.hits.hits.map(i => i._source) }, () => {
    console.log(this.state.MP3info)
})

来自文档:

setState() 并不总是立即更新组件。它可能会批量更新或将更新推迟到以后。这使得在调用 setState() 之后立即读取 this.state 是一个潜在的陷阱。相反,使用 componentDidUpdate 或 setState 回调 (setState(updater, callback)),它们都保证在应用更新后触发。


推荐阅读