Ввод не очищает содержимое даже после изменения состояния в React - PullRequest
1 голос
/ 20 сентября 2019

У меня есть поле ввода со значком «закрыть (x)» рядом с ним.Я обрабатываю состояние, когда значение в поле ввода изменяется, и как только пользователь нажимает Enter , я очищаю значение в состоянии.Однако после повторного рендеринга (из-за изменения состояния) предыдущий ввод все еще остается там в поле ввода.

constructor(props) {
    super(props);
    this.state = {
      filterSearchQuery: null, filterSearch: null}

    this.handleSearchInput = this.handleSearchInput.bind(this);
    this.handleSearchReset = this.handleSearchReset.bind(this);
}

handleSearchInput(e) {
     //   e.preventDefault();
    let val = e.target.value;
    if (e.keyCode == 13)
      this.setState({ entries: [], filterSearchQuery: null, filterSearch: val, pageIndex: 0, hasMore: false }, this.loadEntries);
    else
      this.setState({ filterSearchQuery: val });
}

handleSearchReset(e) {
    //e.preventDefault();
    this.setState({ entries: [], pageIndex: 0, hasMore: false, filterSearchQuery: null, filterSearch: null }, this.loadEntries);
}

рендеринг и возврат:

<input type="text" className="outline-none flex-fill pt-0_2em pb-0_2em border-white border-none bg-color-white color-black font-12px font-weight-bold opacity-0_9" value={this.state.filterSearchQuery} placeholder="Search in results." onKeyUp={(e) => this.handleSearchInput(e)} onChange={(e) => this.handleSearchInput(e)} autoFocus={true} />
{
    (this.state.filterSearchQuery && this.state.filterSearchQuery.length > 0) &&
    <div className="">
    <button type="button" className="close" aria-label="Close" onClick={this.handleSearchReset}>
        <span aria-hidden="true">&times;</span>
    </button>
 </div>
}

Функция handleSearchReset работает и устанавливает ожидаемое состояние.Оба значения filterSearch и filterSearchQuery установлены правильно.Однако после повторного рендеринга значение filterSearchQuery все еще отображается в поле ввода.Как я могу преодолеть это или где я скучаю?

Заранее спасибо.

1 Ответ

1 голос
/ 20 сентября 2019

Поскольку вы используете контролируемые компоненты, просто , установив их в null, недостаточно для выполнения очистки.Вместо этого установите для них пустую строку "".Вот минимальный, полный пример:

class Foo extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      filterSearchQuery: "",
      filterSearch: ""
    };

    this.handleSearchInput = this.handleSearchInput.bind(this);
    this.handleSearchReset = this.handleSearchReset.bind(this);
  }

  handleSearchInput(e) {
    if (e.keyCode === 13) {
      const {filterSearchQuery} = this.state;
      this.setState({
        filterSearchQuery: "",
        filterSearch: filterSearchQuery,
      });
    }
    else {
      this.setState({
        filterSearchQuery: e.target.value
      });
    }
  }

  handleSearchReset(e) {
    this.setState({
      filterSearchQuery: "",
      filterSearch: ""
    });
  }

  render() {
    const {filterSearchQuery, filterSearch} = this.state;
    return (
      <div>
        <input 
          value={filterSearchQuery} 
          onKeyUp={this.handleSearchInput} 
          onChange={this.handleSearchInput} 
        />
        {filterSearchQuery &&
          <div>
            <button onClick={this.handleSearchReset}>
              <span>&times;</span>
            </button>
          </div>
        }
        {filterSearch &&
          <div>
            ...testing search for '{filterSearch}'...
          </div>
        }
      </div>
    );
  }
}

ReactDOM.render(<Foo />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>

Незначительные замечания:

  • Поскольку вы уже связали this с this.handleSearchFoo в конструкторе, нет необходимостиОболочка функции стрелки в render().
  • Хорошая идея - использовать скобки вокруг всех условных обозначений, чтобы улучшить читаемость и избежать незначительных ошибок.
  • Использование деструктурирование может помочь очиститьмногословие.
  • Избегайте длинных горизонтальных линий для улучшения читабельности.
  • Линия

    (this.state.filterSearchQuery && this.state.filterSearchQuery.length > 0) &&
    

    эквивалентна

    this.state.filterSearchQuery &&
    

    (еслиэто правда, мы знаем, что оно определено и имеет длину> 0).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...