Reagir useContext com “setState”
Recentemente, comecei a usar a API Context React com useContext Hook. Observei que quando temos uma variável de estado, ou seja, const someState = useState(state, setState), alguns desenvolvedores passam setSate diretamente nos valores do provedor e, em seguida, chamam-no em componentes filhos. Isso é uma boa prática?
Quando você não usa o contexto, precisa criar um manipulador para "acessar" setState em um componente filho. Ainda estou usando as funções do manipulador e as passo para os valores do provedor, para importá-las do contexto em filhos.
Passar setState no contexto é uma boa prática? Ainda tenho algumas dúvidas, pois normalmente você não pode passar setState diretamente para um componente. Existe alguma diferença no desempenho ou qualquer outra desvantagem que eu deva considerar?
Obrigada.
Respostas
Se entendi bem, a diferença é que de uma maneira o estado é definido a partir do componente pai e na outra o estado é definido a partir do componente filho. Às vezes, as pessoas fazem dessa maneira para evitar a renderização do loop com a alteração do estado. Não deve haver desvantagens, mas usar funções de manipulador é o caminho normal a seguir.
Edit: Na verdade, acho que entendi errado, mas não tenho certeza. Minha resposta é válida para o caso se você escrever seu próprio provedor que tenha um estado. Se você usar apenas um provedor padrão que forneça um setter, concordo com a resposta de Amel.
Eu pessoalmente não faria isso, mas é mais uma opinião. No entanto, como sempre, depende muito do objetivo que você deseja alcançar.
Um aspecto positivo de fazer isso é que os configuradores de estado fornecidos por useState sempre permanecem os mesmos para cada renderização. Se você passar um valor customizado, você deve evitar que ele mude com muita frequência porque cada componente que escuta a mudança usando useContext seria renderizado novamente.
Eu ainda preferiria passar um objeto personalizado (por exemplo, vindo de um useMemo para evitar reprocessamentos desnecessários) com um retorno de chamada para definir o estado. É mais fácil estender se você quiser fornecer mais coisas no futuro.
Algo assim (exemplo bem simplista, que obviamente não faz sentido assim, é só para compreensão):
function MyProvider({children}) {
const [state, setState] = useState(0);
const provided = useMemo(() => ({
value: state,
setValue: (value) => setState(value)
}, [value]);
return <MyContext.Provider value={provided}>{children}</MyContext.Provider>;
}
Seria mais fácil estender sem alterar o código em todos os lugares onde o contexto é usado. No entanto, ainda acho que não há nada de particularmente ruim em passar apenas o levantador, se é isso que você deseja alcançar.