Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How should I use "redux-thunk" for Async Initial state ? (react/redux)

This question have already been ask several time, however I didn't really understand the answers I found. Using React/Redux, I'm trying to get async data into my initial state with express. Since I'm used to d3 one of my option was to use "d3.json"... but I would be happy to use something else if it's better. From a previous answers on the same topic I add the following code :

// redux action using a dispatcher (think middleware)
export function cool(url) {
    return function(dispatch) {
        return d3.json(url, response => {
            dispatch(setData(response))
        }
    }
}

// redux action
export function setData(data) {
 return {
        type: 'DATA_CHART_ALL',
        data
    }
}

const authorDataReducer = (state = {}, action) => {
    switch (action.type) {
      case 'DATA_CHART_ALL':
        return action.data
      case 'DATA_CHART_FILTER':
        return action.data
      default:
        return state;
    }
};

export authorDataReducer;

I didn't notice it at first, but from what I have understand recently, this code above is following more or less the redux-thunk pattern... so from there I tried to apply redux-thunk but I can't make anything work...

like image 318
Simon Breton Avatar asked Aug 11 '16 23:08

Simon Breton


1 Answers

Your question is not very clear but I will try to answer as good as possible. Redux-thunk is a middleware that you use to dispatch async actions. You initialize it when the redux store is being created as such:

import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import rootReducer from './reducers/index';

const store = createStore(
    rootReducer,
    applyMiddleware(thunk)
);

For loading async data, you will need to dispatch an action even if it's for the initial state. If you are using react, you could to this when your highest order component has mounted.

import React, { Component, PropTypes } from 'react';
import { connect } from 'react-redux';

import { fetchTodos } from '../action';
import TodoList from './TodoList';

class App extends Component {

    constructor(props) {
        super(props);
    }

    componentWillMount() {
        this.props.fetchTodos();
    }

    render() {
        return (
            <TodoList
                todos={this.props.todos}
            />
        );
    }
}

App.propTypes = {
    todos: PropTypes.array.isRequired
};

const mapStateToProps = (state, ownProps) => ({
    todos: state.todos
});

export default connect(
    mapStateToProps,
    {
        fetchTodos: fetchTodos
    }
)(App);

this will trigger an action which could look like this

export const fetchTodos = () => {
    return (dispatch) => {
        return fetch(url).then((response) => {
            disptach({
                 type: 'received_todos',
                 payload: {
                     response.json()
                 }
            });
        });
    }
}

As you can see, I didn't use d3 but fetch. I guess any library is good as long as you are returning a Promise.

like image 53
Max Moeschinger Avatar answered Oct 13 '22 17:10

Max Moeschinger