Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

219
Visualizações
Multiple calls to state updater from useState in component causes multiple re-renders

I'm trying React hooks for the first time and all seemed good until I realised that when I get data and update two different state variables (data and loading flag), my component (a data table) is rendered twice, even though both calls to the state updater are happening in the same function. Here is my api function which is returning both variables to my component.

const getData = url => {

    const [data, setData] = useState(null);
    const [loading, setLoading] = useState(true);

    useEffect(async () => {

        const test = await api.get('/people')

        if(test.ok){
            setLoading(false);
            setData(test.data.results);
        }

    }, []);

    return { data, loading };
};

In a normal class component you'd make a single call to update the state which can be a complex object but the "hooks way" seems to be to split the state into smaller units, a side effect of which seems to be multiple re-renders when they are updated separately. Any ideas how to mitigate this?

over 4 years ago · Santiago Trujillo
2 Respostas
Responde à pergunta

0

This also has another solution using useReducer! first we define our new setState.

const [state, setState] = useReducer(
  (state, newState) => ({...state, ...newState}),
  {loading: true, data: null, something: ''}
)

after that we can simply use it like the good old classes this.setState, only without the this!

setState({loading: false, data: test.data.results})

As you may noticed in our new setState (just like as what we previously had with this.setState), we don't need to update all the states together! for example I can change one of our states like this (and it doesn't alter other states!):

setState({loading: false})

Awesome, Ha?!

So let's put all the pieces together:

import {useReducer} from 'react'

const getData = url => {
  const [state, setState] = useReducer(
    (state, newState) => ({...state, ...newState}),
    {loading: true, data: null}
  )

  useEffect(async () => {
    const test = await api.get('/people')
    if(test.ok){
      setState({loading: false, data: test.data.results})
    }
  }, [])

  return state
}

Typescript Support. Thanks to P. Galbraith who replied this solution, Those using typescript can use this:

useReducer<Reducer<MyState, Partial<MyState>>>(...)

where MyState is the type of your state object.

e.g. In our case it'll be like this:

interface MyState {
   loading: boolean;
   data: any;
   something: string;
}

const [state, setState] = useReducer<Reducer<MyState, Partial<MyState>>>(
  (state, newState) => ({...state, ...newState}),
  {loading: true, data: null, something: ''}
)

Previous State Support. In comments user2420374 asked for a way to have access to the prevState inside our setState, so here's a way to achieve this goal:

const [state, setState] = useReducer(
    (state, newState) => {
        newWithPrevState = isFunction(newState) ? newState(state) : newState
        return (
            {...state, ...newWithPrevState}
        )
     },
     initialState
)

// And then use it like this...
setState(prevState => {...})

isFunction checks whether the passed argument is a function (which means you're trying to access the prevState) or a plain object. You can find this implementation of isFunction by Alex Grande here.


Notice. For those who want to use this answer a lot, I decided to turn it into a library. You can find it here:

Github: https://github.com/thevahidal/react-use-setstate

NPM: https://www.npmjs.com/package/react-use-setstate

over 4 years ago · Santiago Trujillo Relatório

0

Batching update in react-hooks https://github.com/facebook/react/issues/14259

React currently will batch state updates if they're triggered from within a React-based event, like a button click or input change. It will not batch updates if they're triggered outside of a React event handler, like an async call.

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda