【问题标题】:Delay in filter input basic reactJS search function过滤器输入延迟基本reactJS搜索功能
【发布时间】:2020-08-17 12:12:34
【问题描述】:

我为在线练习制作了一个基本的电话簿应用程序,可让您将人们的姓名和电话号码保存到电话簿中。还有一个搜索输入,可让您根据名称过滤结果。一切正常,但是,我无法弄清楚的一件奇怪的事情是过滤器总是延迟一个字符,当用户在搜索栏中输入字符时状态不会立即更新?

例如:

如果我在搜索中输入“J”,它将过滤“”

如果我然后输入“a”,那么现在“Ja”在搜索栏中,它将过滤“J”

如果我然后退格“a”,那么现在“J”在搜索栏中,它将过滤“Ja”

等等……过滤器总是落后一步。

我是新来的国家,似乎无法解决它。谁能帮我吗?谢谢。 (另外,如果对我的代码有任何其他建设性的批评可以改进它,我非常开放和欣赏)

我的代码:

const phonebook = [
  {
    id: 1,
    details: {
      name: 'Jim',
      number: '55 748 192'
    }
  },
  {
    id: 2,
    details: {
      name: 'Jason',
      number: '55 111 192'
    }
  },
  {
    id: 3,
    details: {
      name: 'Jonesy',
      number: '55 983 122'
    }
  },
  {
    id: 4,
    details: {
      name: 'Jack',
      number: '0408 729 000'
    }
  },

]


const App = (props) => {

  const [bookData, setBookData] = useState(props.props)
  const [newName, setNewName] = useState('')
  const [newNumber, setNewNumber] = useState('')
  const [theFilter, setTheFilter] = useState('')
  const [namesToShow, setNamesToShow] = useState(bookData.map(person => person.details))

  const [errorMessage, setErrorMessage] = useState('')

  console.log('the filter', theFilter, namesToShow)

  const addNumber = (event) => {
    event.preventDefault()
    const numberObject = {
      id: bookData.length + 1,
      details: {
        name: newName,
        number: newNumber,
      }
    }
    if(numberObject.details.name !== "" && numberObject.details.number !== '') {
      setBookData(bookData.concat(numberObject))
      setNewName('')
      setNewNumber('')
      setErrorMessage('')
    } else {
      if(numberObject.details.name === "" && numberObject.details.number === "") {
        setErrorMessage('You must enter a name and number!!')
      } else if(numberObject.details.number === "") {
        setErrorMessage('You must enter a number!!')
      } else {
        setErrorMessage('You must enter a name!!!')
      }
    }
  }

  const handleFilterChange = (event) => {
    setTheFilter(event.target.value)
    console.log(theFilter)
    if(theFilter === '') {
      setNamesToShow(bookData.map(person => person.details))
      console.log('help')
    } else {
      console.log('bookData', bookData.map(person => person.details))
      setNamesToShow(bookData.map(person => person.details).filter(person => person.name.includes(theFilter)))
      console.log('filter', theFilter)
      console.log('potential namestoshow?', bookData.map(person => person.details).filter(person => person.name.includes(theFilter)))
      console.log('namestoshow', namesToShow)
    }
  }

  const handleNameChange = (event) => {
    setNewName(event.target.value)
  }

  const handleNumberChange = (event) => {
    setNewNumber(event.target.value)
  }

  return (
    <>
      <h1>Phonebook</h1>
      <div>
        <input value={theFilter} onChange={handleFilterChange} placeholder='Search for a name' />
        {namesToShow.map(person => (
          <p>{person.name}: {person.number}</p>
          ))}
      </div>
      <form>
        <input value={newName} onChange={handleNameChange} placeholder='Enter a name...'/>
        <input value={newNumber} onChange={handleNumberChange} placeholder='Enter a number...'/>
        <button type='submit' onClick={addNumber}>Save</button>
      </form>
      <div>
        {errorMessage}
      </div>
    </>
  )
}



ReactDOM.render(
  <App props={phonebook} />,
  document.getElementById('root')
)

【问题讨论】:

  • 这能回答你的问题吗? Why calling react setState method doesn't mutate the state immediately? 状态更新是异步的,所以在 handleFilterChange 中,当你 setTheFilter(event.target.value) 之后在同一个函数中尝试使用 theFiltertheFilter 具有来自 current 渲染周期的值,而不是下一个排队了。
  • 要么在函数中使用值event.target.value 进行过滤,要么使用useEffect 挂钩适当地响应theFilter 状态值更新。
  • 非常感谢,这是有道理的。我在 handleFilterChange 中切换了 event.target.value 的过滤器并且工作正常。

标签: javascript reactjs search filter


【解决方案1】:

这是因为 useState 更新是批处理的。当您设置新状态时,它不会立即设置。因此,功能组件中的最佳方法是使用依赖于该变量的 useEffect 挂钩。例如:

useEffect(() => {
  doSomeJob(theFilter);
}, [theFilter])

其中 [theFilter] 是一个变量数组,这些变量的更改应该会触发该效果。

【讨论】:

    猜你喜欢
    • 2019-12-21
    • 2012-06-07
    • 2014-05-08
    • 1970-01-01
    • 2012-05-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-27
    相关资源
    最近更新 更多