El estado de Redux no se actualiza después de agregar una publicación de blog

Bien, tengo esta aplicación React con un backend creado con Node y Express. Tengo dos puntos finales, getAllPostsy createPost. getAllPostsdevuelve una matriz de publicaciones y createPostsdevuelve un objeto con estado y mensaje.

Entonces, en la interfaz, estoy obteniendo los datos en las acciones de Redux de esta manera:

export const getPosts = () => async ( dispatch ) => {
    try {
        const config = {
            headers: {
                'Content-Type': 'application/json'
            }
        }

        const { data } = await axios.get( '/api/posts', config );

        dispatch({
            type: GET_POSTS_SUCCESS,
            payload: data
        });

    } catch ( error ) {
        console.log( error ) 
    }
}

export const createPost = ( postData ) => async ( dispatch ) => {
    try {
        const config = {
            headers: {
                'Content-Type': 'application/json'
            }
        }

        const { data } = await axios.post( '/api/post', postData, config );

        dispatch({
            type: CREATE_POST_SUCCESS,
            payload: data
        });

    } catch ( error ) {
        console.log( error )        
    }
}

Y los reductores se ven así:

export const getPostsReducer = ( state = [], action ) => {
    switch ( action.type ) {
        case GET_POSTS_SUCCESS:
            return {
                loading: false,
                posts: action.payload
            };
        default:
            return state;
    }
}

export const createPostReducer = ( state = [], action ) => {
    switch ( action.type ) {
        case CREATE_POST_SUCCESS:
            return {
                loading: false,
                response: action.payload
            };
        default:
            return state;
    }
}

Puedo representar con éxito todas las publicaciones en la carga de la primera página, pero cuando creo una publicación, la recién creada no se agrega de inmediato. Si reviso las herramientas de desarrollo de Redux, no veo la lista actualizada. Pero solo los renderizados o las herramientas de desarrollo muestran la lista actualizada después de recargar la página. .

Estoy despachando getPostsen un componente así:

useEffect( () => {
        dispatch( getPosts() );
}, [ dispatch ] )

y despachando el createPosten otro componente submitHandlercomo este:

const submitHandler = ( e ) => {
        e.preventDefault();
        dispatch( createPost( { post } ) );
}

También intenté poner el submitHandleren el mismo componente donde getPostsse llama para que el envío activara useEffecty llamara getPostsde nuevo para obtener la lista actualizada. Pero eso tampoco funciona. Además de eso, también intenté agregar la lista devuelta getPostscomo dependencia en useEffect, pero si la registro, se imprime una cantidad infinita en el registro.

¿Qué estoy haciendo mal aquí?

Answer

Cambiaría un poco la estructura:

en el método createPost en lugar de enviar, solo devolvería datos

export const createPost = ( postData ) => async ( dispatch ) => {
    try {
        const config = {
            headers: {
                'Content-Type': 'application/json'
            }
        }

        const { data } = await axios.post( '/api/post', postData, config );

        return data;

    } catch ( error ) {
        console.log( error )        
    }
}

y luego en tu código yo

const submitHandler = ( e ) => {
    e.preventDefault();
    createPost({post}).then(data=>{
    dispatch({type:CREATE_POST, data})
 }

esto definitivamente debería funcionar

El problema parece ser que React no sabe que se creó una nueva publicación. Tendrás que llamar getPosts()después de que te createPost()hayan llamado.

const submitHandler = (e) => {
  e.preventDefault();
  dispatch(createPost({ post }));
  dispatch(getPosts());
}

Si desea estructurar sus servicios de una manera más centralizada y escalable, consulte la publicación de mi blog sobre los servicios de React: https://schneider-lukas.com/blog/react-connect-rest-api . También podría almacenar las publicaciones en el componente Proveedor para que estén disponibles para todos los componentes en el árbol, o mejor aún, crear un Contexto, Proveedor y Consumidor separados para manejar las publicaciones.

Nuevo colaborador
Lukas Schneider is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.