Задержка в входных данных фильтра c reactJS функция поиска - PullRequest
0 голосов
/ 03 мая 2020

Я сделал базовое приложение для телефонной книги c для онлайн-упражнения, которое позволяет вам сохранять имена и телефонные номера людей в телефонной книге. Существует также поисковый ввод, который позволяет фильтровать результаты по имени. Все это работает, однако, одна странная вещь, которую я не могу понять, это то, что фильтр всегда задерживается на один символ, состояние не обновляется сразу, когда пользователь вводит символ в строку поиска?

Например:

, если я наберу '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')
)

1 Ответ

1 голос
/ 03 мая 2020

Это потому, что обновления useState являются пакетными. Когда вы устанавливаете новое состояние, оно не устанавливается сразу. Таким образом, лучший подход в функциональном компоненте заключается в использовании ловушки useEffect, которая зависит от этой переменной. Например:

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

Где [theFilter] - массив переменных, изменение которых должно вызвать этот эффект.

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