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

187
Vistas
Necesito ayuda para mostrar contenido de la tienda redux

Estoy tratando de recuperar información de mi backend y mostrarla. Puedo obtener los datos en mi tienda redux bien, pero cuando trato de mostrarlos en la página, aparece un 'título' de propiedad de error indefinido que no se puede leer. No siempre ocurre, pero cada vez que actualizo lo hace. ¿Algunas ideas? Aquí está el archivo en cuestión. Feliz de compartir otra información, pero estoy bastante seguro de que tanto mi backend como redux funcionan correctamente porque puedo recuperar y mostrar datos en otros lugares.

 import '../../styles/article.css'; import { useEffect, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { getThread } from '../../store/actions/forum_actions'; import { clearThread } from '../../store/actions'; const Thread = (props) => { const [loading, setLoading] = useState(true); const threads = useSelector((state) => state.threads); const thread = threads?.current; const dispatch = useDispatch(); useEffect(() => { dispatch(getThread(props.match.params.id)); setLoading(false); }, [dispatch, props.match.params.id]); useEffect(() => { return () => { dispatch(clearThread()); }; }, [dispatch]); return ( <> {loading ? ( <> <p>Loading</p> </> ) : ( <> <p>{thread.title}</p> </> )} </> ); }; export default Thread;

Aquí está el reductor:

 import { ADD_THREAD, GET_THREADS, GET_THREAD, CLEAR_THREAD } from '../types'; export default function threadReducer(state = {}, action) { switch (action.type) { case ADD_THREAD: return { ...state, lastThreadAdded: action.payload, success: true }; case GET_THREADS: return { ...state, threads: action.payload }; case GET_THREAD: return { ...state, current: action.payload }; case CLEAR_THREAD: return { ...state, current: null }; default: return state; } }

Aquí está la acción

 import * as threads from './index'; import axios from 'axios'; import { getAuthHeaders } from '../../components/utils/tools'; axios.defaults.headers.post['Content-Type'] = 'application/json'; export const getThread = (id) => { return async (dispatch) => { const request = await axios.get(`/forum/thread/${id}`); dispatch(threads.getThread(request.data)); try { } catch (error) { dispatch(threads.errorGlobal('Error retrieving thread')); } }; };
about 4 years ago · Juan Pablo Isaza
3 Respuestas
Responde la pregunta

0

La razón por la que sucede es porque la acción que está enviando es Async ( dispatch(getThread(props.match.params.id)); ) y, por lo tanto, la ejecución del código no esperará el resultado de la API, ejecutará la siguiente declaración que es setLoading(false) . Está haciendo que su carga se detenga antes de la respuesta de la API y, por lo tanto, está obteniendo un error indefinido.

Solución:

Redutor:

 import { ADD_THREAD, GET_THREADS, GET_THREAD, CLEAR_THREAD, LOADING_THREAD } from '../types'; export default function threadReducer(state = {}, action) { switch (action.type) { case LOADING_THREAD: return { ...state, loadingThreads: action.payload }; //modified case ADD_THREAD: return { ...state, lastThreadAdded: action.payload, success: true }; case GET_THREADS: return { ...state, threads: action.payload }; case GET_THREAD: return { ...state, current: action.payload }; case CLEAR_THREAD: return { ...state, current: null }; default: return state; } }

Acción:

 import * as threads from './index'; import axios from 'axios'; import { getAuthHeaders } from '../../components/utils/tools'; axios.defaults.headers.post['Content-Type'] = 'application/json'; export const getThread = (id) => { return async (dispatch) => { try { dispatch(threads.loadingThread(true)); const request = await axios.get(`/forum/thread/${id}`); dispatch(threads.getThread(request.data)); dispatch(threads.loadingThread(false)); } catch (error) { dispatch(threads.loadingThread(false)); dispatch(threads.errorGlobal('Error retrieving thread')); } }; };

Componente:

 import '../../styles/article.css'; import { useEffect, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { getThread } from '../../store/actions/forum_actions'; import { clearThread } from '../../store/actions'; const Thread = (props) => { const threads = useSelector((state) => state.threads); const loading = useSelector((state) => state.loadingThreads); //modified const thread = threads?.current; const dispatch = useDispatch(); useEffect(() => { dispatch(getThread(props.match.params.id)); setLoading(false); }, [dispatch, props.match.params.id]); useEffect(() => { return () => { dispatch(clearThread()); }; }, [dispatch]); return ( <> {loading ? ( <> <p>Loading</p> </> ) : ( <> <p>{thread.title}</p> </> )} </> ); }; export default Thread;
about 4 years ago · Juan Pablo Isaza Denunciar

0

Sugeriría haber definido initialState para el reductor

en cambio

state = {}

 const initialState = { current:{}, threads: [], success: false } function threadReducer(state = initialState, action)

esto lo ayudará a administrar el estado intermedio.

Además, el estado de carga en el componente no siempre está alineado. Considere usar

isLoading = useSelector(loadingSelector)

en lugar useState

about 4 years ago · Juan Pablo Isaza Denunciar

0

Puede simplificar los flujos asíncronos de Redux implementando el patrón de repositorio sin un middleware para manejar una llamada API y enviar un estado. Las llamadas API también se pueden encapsular en enlaces. Por ejemplo, echa un vistazo a este fragmento de código, no está relacionado con tu proyecto, pero puedes usarlo como punto de partida:

 export const useCustomerRepository = () => { const dispatch = useDispatch<Dispatch<CustomerAction>>(); const customerState = useSelector((state: RootState) => state.customerState); const customerApi = useCustomerApi(); const list = async () => { try { dispatch({ type: 'CUSTOMER:LISTING', flag: true }); const customers = await handleAxiosApi<Customer[]>(customerApi.list()); dispatch({ type: 'CUSTOMER:LIST', customers }); } catch (error) { dispatch({ type: 'CUSTOMER:LIST_FAILED', message: getResponseErrorMessage(error) }); } finally { dispatch({ type: 'CUSTOMER:LISTING', flag: false }); } }; return {...customerState}; };

Puede echar un vistazo al ejemplo de trabajo completo aquí para simplificar su código.

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