简体   繁体   English

setState之后组件不会重新呈现

[英]Component won't rerender after setState

I recently got started with React and want to build a little application to fetch weather data. 我最近刚开始使用React,并且想要构建一个小应用程序来获取天气数据。 My API has a function to return autocomplete suggestions. 我的API具有返回自动完成建议的功能。 So when my autosuggestion array is not empty I render a list and upon clicking one of the <li>'s I want the value inside of the input box. 因此,当我的自动提示数组不为空时,我呈现一个列表,并在单击<li>'s之一时,我希望该值位于输入框内。 I manage to set the state of my SearchBar but can't change it's value. 我设法设置了SearchBar的状态,但是无法更改其值。

Edit : I try to get my value from changeState() into my <input type="text" placeholder="City, Zip Code, Coordinates" onChange={evt => this.updateInputValue(evt)} /> . 编辑 :我尝试将我的值从changeState()放入我的<input type="text" placeholder="City, Zip Code, Coordinates" onChange={evt => this.updateInputValue(evt)} /> I can search for terms otherwise. 我可以搜索其他术语。

import React from 'react';
import './SearchBar.css';
import Suggestion from './Suggestion';

class SearchBar extends React.Component{
  constructor(props) {
    super(props);
    this.state = {inputValue: ''};
    this.search = this.search.bind(this);
    this.updateInputValue = this.updateInputValue.bind(this);
    this.handleKeyPress = this.handleKeyPress.bind(this);
    this.changeState = this.changeState.bind(this);
  }

  changeState(value) {
    console.log(value);
    // Logs value of text between <li></li>
    this.setState({inputValue: value});
  }

  search() {
    this.props.onSearch(this.state.inputValue);
  }

  updateInputValue(evt) {
    this.setState({
      inputValue: evt.target.value
    });
    this.props.onChange(this.state.inputValue);
  }

  handleKeyPress(e) {
    if(e.key === 'Enter') {
      this.search();
    }
  }

  render() {
    return (
      <div>
        <div className="SearchGroup" onKeyPress={this.handleKeyPress} >
          <input type="text" placeholder="City, Zip Code, Coordinates" onChange={evt => this.updateInputValue(evt)} />
          <a onClick={this.search}>Go</a>
        </div>
        <Suggestion autocomplete={this.props.autocomplete} onSelect={this.changeState} />
      </div>
    );
  }
}

export default SearchBar;

For the sake of completeness my Suggestion.js : 为了完整性,我的Suggestion.js

import React from 'react';
import './Suggestion.css';

class Suggestion extends React.Component{
  constructor(props) {
    super(props);
    this.updateInputField = this.updateInputField.bind(this);
  }

  updateInputField(evt) {
    this.props.onSelect(evt.currentTarget.innerText);
  }

  render(){
      if(this.props.autocomplete && this.props.autocomplete.length > 0) {
        return (
          <div className="Suggestion">
            <ul>
              {
                this.props.autocomplete.map((location) => {
                  return (
                    <li key={location.id} onClick={this.updateInputField}>{location.name}</li>
                  )
                })
              }
            </ul>
          </div>
        );
      } else {
        return <div className="None"></div>
      }
  }
}

export default Suggestion;

I would also prefer to submit location.url in Suggestion , but I could not find a property that matches inside of evt . 我也希望在“ Suggestion提交location.url ,但是找不到与evt内部匹配的属性。

As mentioned in my comment. 如我的评论中所述。 You are setting state and immediately passing state to onChange function in updateInputValue event handler function which is not correct. 您正在设置状态,并立即将状态传递给updateInputValue事件处理函数中的onChange函数,这是不正确的。 Because you won't get the state value updated immediately, the state value updates only when it renders so, pass evt.target.value directly like below 由于您不会立即更新状态值,因此状态值仅在呈现时才更新,因此请像下面这样直接传递evt.target.value

updateInputValue(evt) { 
   this.setState({ inputValue: evt.target.value }); 
   this.props.onChange(evt.target.value);
}

In order to see chnaged value on your input field, you have to pass value prop to input tag like below 为了在您的输入字段上看到更改的值,您必须将value属性传递给输入标签,如下所示

<input type="text" placeholder="City, Zip Code, Coordinates" onChange={evt => this.updateInputValue(evt)} value={this.state.inputValue}/>

I would guess that you are trying to use value from state that isnt there yet, because setState is asynchronous so either use callback on setState 我猜您正在尝试使用尚未存在的状态的值,因为setState是异步的,因此可以在setState上使用回调

updateInputValue(evt) {
  this.setState({
    inputValue: evt.target.value
  }, ()=> this.props.onChange(this.state.inputValue));
}

or, use the value from event directly 或者,直接使用event中的值

updateInputValue(evt) {
  const value = evt.target.value
  this.setState({
    inputValue: value
  });
  this.props.onChange(value)
}

plus you havent assigned value back to your input: 另外,您还没有将值分配回您的输入:

<input type="text" placeholder="City, Zip Code, Coordinates" onChange={evt => this.updateInputValue(evt)} value={this.state.inputValue}/>

The React setState doesn't update the state immediately. React setState不会立即更新状态。 It puts it in the queue and updates the state in batches. 它将其放入队列并批量更新状态。 if you want to access the updated state write the code in the setState callBack 如果要访问更新的状态,请在setState callBack中编写代码

this.setState({ inputValue: evt.target.value},()=> this.props.onChange(this.state.inputValue));

something like this 像这样的东西

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM