Estou tentando aprender ganchos e o useState
método me deixou confusa. Estou atribuindo um valor inicial a um estado na forma de uma matriz. O método set in useState
não está funcionando para mim, mesmo com spread(...)
ou without spread operator
. Eu criei uma API em outro PC que estou chamando e buscando os dados que desejo definir no estado.
Aqui está o meu código:
import React, { useState, useEffect } from "react";
import ReactDOM from "react-dom";
const StateSelector = () => {
const initialValue = [
{
category: "",
photo: "",
description: "",
id: 0,
name: "",
rating: 0
}
];
const [movies, setMovies] = useState(initialValue);
useEffect(() => {
(async function() {
try {
//const response = await fetch(
//`http://192.168.1.164:5000/movies/display`
//);
//const json = await response.json();
//const result = json.data.result;
const result = [
{
category: "cat1",
description: "desc1",
id: "1546514491119",
name: "randomname2",
photo: null,
rating: "3"
},
{
category: "cat2",
description: "desc1",
id: "1546837819818",
name: "randomname1",
rating: "5"
}
];
console.log(result);
setMovies(result);
console.log(movies);
} catch (e) {
console.error(e);
}
})();
}, []);
return <p>hello</p>;
};
const rootElement = document.getElementById("root");
ReactDOM.render(<StateSelector />, rootElement);
O setMovies(result)
bem como setMovies(...result)
não está funcionando. Poderia usar alguma ajuda aqui.
Espero que a variável de resultado seja inserida na matriz de filmes.
fonte
useEffect
talvez não seja a melhor solução, pois não suporta chamadas assíncronas. Portanto, se gostaríamos de fazer alguma validação assíncrona sobre amovies
mudança de estado, não temos controle sobre ela.the updater provided by useState hook
ser assíncrono ou não , ao contrário dothis.state
que poderia ter sido alterado sethis.setState
fosse síncrono, o fechamento em tornoconst movies
permaneceria o mesmo, mesmo queuseState
forneceu uma função síncrona - veja o exemplo na minha respostasetMovies(prevMovies => ([...prevMovies, ...result]));
trabalhou para mimDetalhes adicionais para a resposta anterior :
Embora o React
setState
seja assíncrono (tanto de classe quanto de gancho), e é tentador usar esse fato para explicar o comportamento observado, não é a razão pela qual isso acontece.TLDR: O motivo é um escopo de fechamento em torno de um
const
valor imutável .Soluções:
leia o valor na função render (não dentro das funções aninhadas):
adicione a variável nas dependências (e use a regra react -hooks / exaustive-deps eslint):
use uma referência mutável (quando o acima não for possível):
Explicação por que isso acontece:
Se o assíncrono fosse o único motivo, seria possível
await setState()
.Howerver, ambos
props
estate
são assumidos como inalteráveis durante 1 render .Com ganchos, essa suposição é aprimorada usando valores constantes com a
const
palavra-chave:O valor pode ser diferente entre 2 renderizações, mas permanece uma constante dentro da renderização em si e dentro de quaisquer fechamentos (funções que permanecem mais longas mesmo após a conclusão da renderização, por exemplo,
useEffect
, manipuladores de eventos, dentro de qualquer Promise ou setTimeout).Considere a seguinte implementação falsa, mas síncrona , do tipo React:
fonte
Acabei de reescrever com useReducer, seguindo o artigo @kentcdobs (ref abaixo), que realmente me deu um resultado sólido que não sofre nem um pouco com esses problemas de fechamento.
consulte: https://kentcdodds.com/blog/how-to-use-react-context-effectively
Condensei seu clichê legível para o meu nível preferido de DRYness - ler a implementação do sandbox mostrará como ele realmente funciona.
Aproveite, eu sei que sou !!
com um uso semelhante a este:
Agora tudo persiste sem problemas em todos os lugares em todas as minhas páginas
Agradável!
Graças Kent!
fonte
Agora você deve ver, que o código realmente faz o trabalho. O que não funciona é o
console.log(movies)
. Isso ocorre porquemovies
aponta para o estado antigo . Se você se mudar paraconsole.log(movies)
forauseEffect
, logo acima do retorno, verá o objeto de filmes atualizados.fonte