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

114
Visualizações
How to compare values from react redux state in hooks

I have recently written a table component using hooks , and every time page loads there is an API call to backend, so meanwhile there is a loading Spinner will be shown until there is an response from the API. I'm using redux as state management, so when there is a response from API , an action is dispatched and state is updated. So the problem here is ,usually in class component we can compare prevProps and nextProps using

componentDidUpdate(prevProps){
  if(this.props.someState !== prevProps.someState){
      // do something
    }
}

but i'm not sure how to achieve the same using Hooks. I also referred this stackoverflow question How to compare oldValues and newValues on React Hooks useEffect?

but this solution doesn't seem to be working in my case . I did try creating custom hook usePrevious and creating a ref to compare current value ,this didn't solve my issue.

Here's my part of code.

let loading = true;

let tableData = useSelector((state) => {
   
    if (
      state.common.tableDetails.data &&
      state.common.tableDetails.status === true
    ) {
      loading = false;
      return state.common.tableDetails.data;
    }
   
    if (
      state.common.tableDetails.data &&
      state.common.tableDetails.status === false
      
    ) {
      loading = true;
    }
    return [];
  });

// table component

<Fragment>
  { 
   loading === true ? <Spinner />  :  <TableComponent tableData={tableData }/>
   }
</Fragment>

So whenever the component loads, if there is any data present in redux state , that data is shown and no comparison is done for prevProps and nextProps because of which Loading spinner won't show up and after a response of newly called api state will be update and new data will be shown in Table.

UPDATE 1: Here's the code for dispatch and action and reducer

 useEffect(() => {
    
    dispatch(fetchDetails(params.someID));

  }, [dispatch, params.someID]);

Action File

export const fetchDetails = (data) => (dispatch) => {
  axios
    .post(
      `${SomeURL}/fetchAll`,
      data
    )
    .then((res) => {
      if (res.data.status) {
        dispatch({
          type: FETCH_DETAILS,
          payload: res.data,
        });
      }
    })
    .catch((err) => console.log(err));
};

Reducer File

const initialState = {
  tableDetails: {},
};

export default function (state = initialState, action) {
  switch (action.type) {
    case FETCH_DETAILS:
      return {
        ...state,
        tableDetails: action.payload,
      };

    default:
      return state;
  }
}


about 4 years ago · Juan Pablo Isaza
2 Respostas
Responde à pergunta

0

You can implement simple validation to achieve what you want. I will assume your tableData has an id, then you can validate like this:

useEffect(() => {
    // don't fetch the same table
    if(tableData?.id !== params.someID {
      dispatch(fetchDetails(params.someID));
    }
}, [dispatch, params.someID, tableData?.id]);

UPDATE 1

To compare previous table data to new feched one you could do that in the action creator:

  1. move loading state to redux store.
  2. use getState function which is the second argument recived by action creator (assuming that you are using redux-thunk)
  3. before dispatching the action, compare new tableData with data in the store(prev tableData).
  4. do your check and update loading state.

export const fetchDetails = (data) => (dispatch, getState) => {
  axios
    .post(
      `${SomeURL}/fetchAll`,
      data
    )
    .then((res) => {
      if (res.data.status) {
        const prevTableData = getState().tableData;
        
        // compare prev and new table data
        if(isDiff(prevTableData, res.data) {
            // Do something...
        }
        dispatch({
          type: FETCH_DETAILS,
          payload: res.data,
        });
      }
    })
    .catch((err) => console.log(err));
};

about 4 years ago · Juan Pablo Isaza Relatório

0

The right way is to use redux reselect package https://github.com/reduxjs/reselect. Redux team recommends it.

reselect is designed specifically for this kind of scenarios. It also uses memoization under the hood. You can make your custom selectors and use them in scenarios like this.

You can make a seperate file for all the reselect functions like this

//select file (eg: selectors.js)
import { createSelector } from "reselect";

const tableDetails = state => state.common.tableDetails;

function checkDataFunction(details){
    if (
      details.data &&
      details.status === true
    ) {
      return {
        loading: false,
        data: details.data
      }
    }
   
    else if (
      details.data &&
      details.status === false
      
    ) {
      return {
        loading: true,
        data: []
      }
    }

    return {
      loading: true,
      data: []
    };
}

//redux selector
//enables you to make your own custom selector
export const checkData = createSelector(
  tableDetails,
  checkDataFunction
);

Now in your main component file where you want to use this just import it and use it as any other selector

//main component file (eg: App.js)
import {checkData} from './selectors';


export default function App(){
  const tableData = useSelector(checkData);

  useEffect(() => {
    //continue with your logic here
  },[tableData.loading])

  //...
}
about 4 years ago · Juan Pablo Isaza 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