简体   繁体   English

延迟滤波器输入基本 reactJS 搜索 function

[英]Delay in filter input basic reactJS search function

I've made a basic phonebook application for an online exercise that allows you to save people's names and phone numbers to a phone book.我为在线练习制作了一个基本的电话簿应用程序,它允许您将人们的姓名和电话号码保存到电话簿中。 There is also a search input that allows you to filter results based on name.还有一个搜索输入,可让您根据名称过滤结果。 It all works, however, one weird thing that I can't figure out is that the filter is always delayed by one character, the state isn't updated immediately when the user inputs a character into the search bar?一切正常,但是,我无法弄清楚的一件奇怪的事情是过滤器总是延迟一个字符,当用户在搜索栏中输入字符时,state 不会立即更新?

For example:例如:

if I type 'J' into the search it will filter for ''如果我在搜索中输入“J”,它将过滤“”

if I then type 'a' so now 'Ja' is in the search bar it will filter for 'J'如果我然后输入“a”,那么现在“Ja”在搜索栏中,它将过滤“J”

if I then backspace the 'a' so now 'J' is in the search bar it will filter for 'Ja'如果我然后退格'a'所以现在'J'在搜索栏中它将过滤'Ja'

and so on... the filter is always one step behind.等等……过滤器总是落后一步。

I'm new to state's and can't seem to fix it.我是新来的国家,似乎无法解决它。 Can anyone help me out?谁能帮我吗? thanks.谢谢。 (also if there is any other constructive critique to my code that would improve it I'm very open and appreciative of it) (如果对我的代码有任何其他建设性的批评可以改进它,我会非常开放和欣赏它)

my Code:我的代码:

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')
)

This is because useState updates is batched.这是因为 useState 更新是批处理的。 When you set a new state it is not set immediately.当您设置一个新的 state 时,它不会立即设置。 So the best approach in a functional component would be to use a useEffect hook that depends on this variable.因此,功能组件中的最佳方法是使用依赖于该变量的 useEffect 挂钩。 For example:例如:

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

Where [theFilter] is an array of variables which change should fire that effect.其中 [theFilter] 是一个变量数组,这些变量的变化应该会触发这种效果。

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

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