Добавление изменения установленного состояния вызывает бесконечный цикл в React - PullRequest
0 голосов
/ 26 сентября 2019

Я пытаюсь создать автономный нечеткий поиск, используя gatsby (реагировать) и Fuse.js, и у меня возникает проблема, связанная с сохранением искомых терминов с помощью setState.

Я получаю следующую ошибку:Слишком много перерисовок.React ограничивает количество рендеров для предотвращения бесконечного цикла.

Я не уверен, как сохранить новое состояние (код ниже)

 const [posts, setPosts] = useState(null)
    useEffect(() => {
        fetch("/index.json")
            .then(response => response.json())
            .then(function(data) {
                setPosts(data.data.allContentfulPost.edges)
            })
    }, [])

    if (posts) {
        var list = posts //returns 326 items
        var options = {
            shouldSort: true,
            threshold: 0.6,
            location: 0,
            distance: 100,
            maxPatternLength: 32,
            minMatchCharLength: 1,
            keys: ["node.title", "node.meta"],
        }
        var fuse = new Fuse(list, options)
        var results = fuse.search("marketing") //returns 11 items
        setPosts(results) //causes infinite loop
    }

Ответы [ 2 ]

0 голосов
/ 26 сентября 2019

Одним из способов решения проблемы является использование другого состояния для отфильтрованных сообщений.И сохраните оригинальные посты для дальнейшего использования:

const [posts, setPosts] = useState([]);
const [filteredPosts, setFilteredPosts] = useState([]);

useEffect(() => {
    fetch("/index.json")
        .then(response => response.json())
        .then(function(data) {
            setPosts(data.data.allContentfulPost.edges)
        })
}, []);

useEffect(() => {
  var options = {
      shouldSort: true,
      threshold: 0.6,
      location: 0,
      distance: 100,
      maxPatternLength: 32,
      minMatchCharLength: 1,
      keys: ["node.title", "node.meta"],
  }
  var fuse = new Fuse(posts, options)
  var results = fuse.search("marketing") //returns 11 items
  setFilteredPosts(results) 
}, [posts])
0 голосов
/ 26 сентября 2019

За исключением редких случаев использования, вы не должны вызывать setState непосредственно в методе визуализации ваших компонентов, и если вы делаете это, вам нужно быть осторожным, чтобы выбрать правильное условие для этого.

Обычно это так, если ваше состояние зависит от реквизита, предоставленного компоненту.Метод жизненного цикла компонента на основе класса называется getDerivedStateFromProps.Здесь вам это не нужно.

Похоже, вы пытаетесь сузить результат от конечной точки API.Преобразование может быть выполнено в обратном вызове fetch перед вызовом setPosts:

useEffect(() => {
    fetch("/index.json")
        .then(response => response.json())
        .then(function(data) {
            const allPosts = data.data.allContentfulPost.edges;
            const options = {
                shouldSort: true,
                threshold: 0.6,
                location: 0,
                distance: 100,
                maxPatternLength: 32,
                minMatchCharLength: 1,
                keys: ["node.title", "node.meta"],
            }
            const fuse = new Fuse(allPosts, options)
            const found = fuse.search("marketing")

            setPosts(found);
        })
}, [])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...