onChange 和 setState 在我的代码中不能一起工作

onChange and setState don't work together in my code

我正在尝试构建一个搜索框。但是,当我想在输入内容时设置状态时,该框只是不允许我输入任何内容。

这是调用搜索框组件的class

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;

如果我在 open & closeDisplay 中评论两个 setStates,它工作正常,它相应地打印出打开和关闭。但是,一旦我启用 setState,输入框就不允许我输入任何内容。

感谢任何帮助。

你的代码写错了。 connectSearchBox 用于将组件连接到 Algolia api。这是组件定义的一次性设置。它 returns 一个高阶组件,用 api 特征包装了给定的组件。可以看源码here。通过将自定义 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}
        />

使用示例来自 docs. I think what you were trying to achieve was to pass props down to your component but the connectSearchBox already guarantees that any props you pass to the HOC also gets passed down to the your custom search box. Line 335