1

Im new to react and taking a course right now. I find state a bit confusing with regards to updating it with async code. In the tutorial that I am doing I swear it said that you need to use thunk in order to handle updating state with react/redux. I am skeptical of this, and being that I am new, I don't really completely understand that. I have written this react component and reducer, and it works fine in the sense that it will update the blog send it to the server, receive it back, and update the state if a 200 response is received, but I am wondering if there is something wrong with it, and not the proper way to update state with data coming from an http request.

Blog component

import React, {Component} from 'react';
import axios from '../../http/axios/axios';
import Card from '../../components/UI/Card/Card';
import classes from '../Container.css';
import Button from '../../components/UI/Button/Button';
import * as actionTypes from '../../store/actions/actions';
import { connect } from 'react-redux';


    class Blog extends Component{

        toggleApprovedAndUpdate = (blog) => {
            blog.approved = ! blog.approved
            this.props.updateBlog(blog)
        }

        render() {
            let blogs = this.props.blgs.map((b, index) =>
                    <Card
                        title={b.title}
                        description={b.description}
                        approved={b.approved.toString()}
                        imagePath={b.image}
                        action={this.toggleApprovedAndUpdate.bind(this, b)}
                        key={index} />)
            return(
                <div>
                    <div className={classes.Container}>
                        <Button
                            label={"Get all blogs"}
                            action={this.props.getBlogs}
                        />
                        {blogs}
                    </div>
                </div>
            )
        }
    }


    const mapStateToProps = state => {
        return {blgs: state.blog.blogs};

    };

    const mapDispatchToProps = dispatch => {
        return {
            getBlogs: () => {
                axios.get('/blog')
                    .then((response) => {
                        return dispatch({type: actionTypes.GET_ALL_BLOGS, blogs: response.data})
                    })
            },
            updateBlog: (blog) => {
                axios.put('/blog', blog)
                    .then((response) => {
                        return dispatch({type: actionTypes.UPDATE_BLOG, blogs: response.data})
                    })
            }
        }
    };

    export default connect(mapStateToProps, mapDispatchToProps)(Blog);

Blog reducer

import * as actionTypes from './actions';

const initialState = {
    blogs: []
}
const reducer = (state = initialState, action) => {
    switch(action.type){
        case actionTypes.GET_ALL_BLOGS:
            return {
                ...state,
                blogs: action.blogs
            }
        case actionTypes.UPDATE_BLOG:
            return {
                ...state,
                blogs: state.blogs.map((blog) => blog.id === action.blogs.id ? {...blog, approved:action.blogs.approved}: blog )
            }
    }
    return state;
}

export default reducer;
slipperypete
  • 5,358
  • 17
  • 59
  • 99
  • https://stackoverflow.com/questions/35411423/how-to-dispatch-a-redux-action-with-a-timeout/35415559#35415559 this answer covers pretty much various async scenarios. On a side note - you are using index as key when creating components. This is not recommended: https://reactjs.org/docs/lists-and-keys.html#keys Maybe use blog.id instead? – Łukasz Godziejewski Feb 28 '18 at 21:14

1 Answers1

0

My understanding is that you can call async functions as you do in the example, without a middleware. What a middleware like redux-thunk does, is to add IDs in the dispatched actions, 'ordering' them, avoiding race conditions such as the one that is described in Writing Async Code in redux.

Yossi
  • 5,577
  • 7
  • 41
  • 76