Пользовательский крюк React возвращает пустой список при первом рендеринге

#javascript #reactjs #react-hooks

Вопрос:

Для проекта, в котором у меня есть несколько таблиц, для которых нужна строка поиска, я создал пользовательский хук, который фильтрует строки таблицы.

Вот мой код для моего пользовательского фильтрационного крючка:

 import React from 'react'
import { matchSorter } from 'match-sorter'

const useFilterData = (searchValue, keyList, data) => {
  const [filteredList, setFilteredList] = React.useState(data)
  React.useEffect(() => {
    if (searchValue) {
      const filtered = matchSorter(data, searchValue, {
        keys: keyList,
      })
      setFilteredList(filtered)
    } else {
      setFilteredList(data)
    }
  }, [searchValue])

  return [filteredList]
}

export default useFilterData
 

Вот фрагмент кода таблицы

 const data = [{}, {}, {}] // this is a list of objects
const columns = [{'field': 'one'}, {'field': 'two'}, {'field': 'three'}]
const columnKeys = columns.map((c) => c.field)
const [searchValue, setSearchValue] = React.useState('')
const [filteredList] = useFilterData(
    searchValue,
    columnKeys,
    data,
  )

  return (
    <div>
      <Paper>
        <TextField onChange={(e) => setSearchValue(e.target.value)} />
        <DataGrid
          rows={filteredList}
          columns={columns}
        />
      </Paper>
    </div>
  )
}
 

При первом отображении списка filteredList это всегда пустой список, как только вы выполните поиск, а затем очистите значение поиска, данные будут отображаться правильно. Поиск работает так, как я хочу, за исключением того, что возвращается при первом рендеринге.
Я попытался использовать useEffect вот так

 React.useEffect(() => {
    setFilteredList(data)
}, [data])
 

но из-за этого я застрял в бесконечном цикле. Я также попытался быть более откровенным в своем заявлении if,

 if (searchValue !== '')
 

это также ничего не изменило!

Я новичок в крючках, поэтому надеюсь, что мне не хватает чего-то простого. Спасибо.

РЕДАКТИРОВАТЬ: Все еще пытаясь что-то сделать, я сузил проблему, я думаю

   console.log(data)
  const [filteredList, setFilteredList] = React.useState(data)
  console.log(filteredList)
  React.useEffect(() => {
    setFilteredList(data)
  }, [])
  console.log(filteredList)
 

Первый журнал консоли правильно возвращает что-то, последние два всегда возвращают пустой список.

Ответ №1:

Это решит вашу проблему:

 React.useEffect(() => {
    setFilteredList(data)
}, [])