Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

120
Vistas
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 Respuestas
Responde la pregunta

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 Denunciar

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 Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda