Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

113
Views
Cómo comparar valores del estado de reacción redux en ganchos

Recientemente escribí un componente de tabla usando ganchos, y cada vez que se carga la página hay una llamada API al backend, por lo tanto, mientras tanto, se mostrará un Spinner de carga hasta que haya una respuesta de la API. Estoy usando redux como administración de estado, por lo que cuando hay una respuesta de API, se envía una acción y se actualiza el estado. Entonces, el problema aquí es que, por lo general, en el componente de clase podemos comparar prevProps y nextProps usando

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

pero no estoy seguro de cómo lograr lo mismo usando Hooks. También hice referencia a esta pregunta de stackoverflow ¿ Cómo comparar oldValues y newValues en React Hooks useEffect?

pero esta solución no parece funcionar en mi caso. Intenté crear un gancho personalizado usePrevious y crear una referencia para comparar el valor actual , esto no resolvió mi problema.

Aquí está mi parte del código.

 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>

Entonces, cada vez que se carga el componente, si hay datos presentes en el estado redux, esos datos se muestran y no se realiza ninguna comparación para prevProps y nextProps debido a que Loading spinner no aparecerá y después de una respuesta del estado api recién llamado será la actualización y los nuevos datos se mostrarán en la tabla.

ACTUALIZACIÓN 1: Aquí está el código para el envío y la acción y el reductor

 useEffect(() => { dispatch(fetchDetails(params.someID)); }, [dispatch, params.someID]);

Archivo de acción

 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)); };

Archivo reductor

 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 answers
Answer question

0

Puede implementar una validación simple para lograr lo que desea. Asumiré que su tableData tiene una id , luego puede validar así:

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

ACTUALIZAR 1

Para comparar los datos de la tabla anterior con los nuevos, puede hacerlo en el creador de acciones:

  1. mover el estado de loading a la tienda redux.
  2. use la función getState , que es el segundo argumento recibido por el creador de la acción (suponiendo que esté usando redux-thunk)
  3. antes de enviar la acción, compare new tableData con los datos en la tienda (prev tableData ).
  4. haga su verificación y actualice el estado loading .

 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 Report

0

La forma correcta es usar el paquete de selección de redux https://github.com/reduxjs/reselect . El equipo de Redux lo recomienda.

reseleccionar está diseñado específicamente para este tipo de escenarios. También utiliza la memorización bajo el capó. Puede crear sus selectores personalizados y usarlos en escenarios como este.

Puede hacer un archivo separado para todas las funciones de reselección como esta

 //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 );

Ahora, en su archivo de componente principal donde desea usar esto, simplemente impórtelo y utilícelo como cualquier otro 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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!