onChange и setState не работают вместе в моем коде - PullRequest
1 голос
/ 09 июня 2019

Я пытаюсь построить окно поиска. Однако, когда я хочу установить состояние, когда что-то набирается, поле просто не позволяет мне ничего вводить.

Это класс, который вызывает компонент окна поиска

export default class Tagsearch extends Component {

  constructor(props) {
    super(props);

    this.state = {
      hitsDisplay:false,
      inputContent:"",
      tags:[]
    };
  }
  openDisplay = () => {
    console.log("open")
    // this.setState({ hitsDisplay: true })
  }

  closeDisplay = () => {
    console.log("close")
    // this.setState({ hitsDisplay: false })
  }

  render() {

    let inputTags = (
      this.state.tags.map((tag, i) => 
        <li key={i} style={styles.items}>
          {tag}
          <button onClick={() => this.handleRemoveItem(i)}>
            (x)
          </button>
        </li>
      )
    )

    let result = (
      <div className="container-fluid" id="results">

      </div>
    )

    if (this.state.hitsDisplay) {
      result = (
        <div className="container-fluid" id="results">
          <div className="rows">
            <MyHits handleSelect={this.handleSelect}/>
          </div>

          <div className="rows">
            <Pagination />
          </div>
        </div>
      )
    }

    return (
      <InstantSearch
        appId="*******"
        apiKey="***********************"
        indexName="tags"
      >
        {inputTags}
        <SearchBox  
          connectSearchBox={connectSearchBox}
          openDisplay={this.openDisplay}
          closeDisplay={this.closeDisplay}
        />
        {result}

      </InstantSearch>
    )
  }
}

Ниже приведен компонент окна поиска

const SearchBox = props => {

  let { 
    connectSearchBox,
    openDisplay,
    closeDisplay
  } = props;

  const CustomSearchBox = connectSearchBox(({ currentRefinement, refine }) => {
    const handleChange = (e, refine) => {
      refine(e.target.value)
      // console.log(e.target.value)
      if (e.target.value !== "") {
        openDisplay();
      } else {
        closeDisplay();
      }
    }

    return (
      <label>
        <ul style={styles.container}>
          <input
            style={styles.input}
            type="text"
            value={currentRefinement}
            onChange={e => handleChange(e, refine)}
          />
        </ul>
      </label>
    )
  })

  return (
    <CustomSearchBox />
  )
}

export default SearchBox;

Если я прокомментирую два setStates в open & closeDisplay, он будет работать нормально, распечатывает соответственно open и close. Однако, как только я включил setState, поле ввода просто не позволяет мне вводить что-либо.

Любая помощь приветствуется.

1 Ответ

1 голос
/ 09 июня 2019

Ваш код написан неправильно. connectSearchBox предназначен для подключения компонента к API Algolia. Это однократная настройка для определения компонента. Он возвращает компонент более высокого порядка, который оборачивает данный компонент функциями API. Вы можете увидеть исходный код здесь . Поместив свой пользовательский SearchBox в функцию SearchBox, вы заставляете компонент перестраиваться и переподключаться в каждом цикле render (), тем самым не сохраняя состояние. Вот почему, как только вы setState текст поиска исчезнет.

import { connectSearchBox } from 'react-instantsearch-dom';

const CustomSearchBox = ({ currentRefinement, refine, openDisplay, closeDisplay, ...props }) => {
    const handleChange = (e, refine) => {
      refine(e.target.value)
      if (e.target.value !== "")
        openDisplay();
      else
        closeDisplay();
    }

    return (
      <label>
        <ul style={styles.container}>
          <input
            style={styles.input}
            type="text"
            value={currentRefinement}
            onChange={e => handleChange(e, refine)}
          />
        </ul>
      </label>
    )
  })

export default connectSearchBox(CustomSearchBox);

Использование

import CustomSearchBox from './CustomSearchBox'
...
       <CustomSearchBox  
          openDisplay={this.openDisplay}
          closeDisplay={this.closeDisplay}
        />

Пример использования из документов . Я думаю, что вы пытались добиться, чтобы передать реквизиты в ваш компонент, но connectSearchBox уже гарантирует, что любые реквизиты, которые вы передаете в HOC, также передаются в ваше поле пользовательского поиска. Строка 335

...