Azilhan
Azilhan

Reputation: 369

React - Redux - Connect data fetched to Component

I am creating a React application and integrating Redux to it in order to manage the state and do network requests.

I followed the Todo tutorial and I am following the async example from the redux website, but I am stucked.

Here is my problem, I want, in my application, to fetch a user from a remote server. So the server send me a json array containing an object (maybe it's better if the server send me directly an object ? ) The json I obtain looks like that (I put only two fields but there are more in real) :

[{first_name: "Rick", "last_name": "Grimes"}]

Anyway I can fetch the data from the server but I can't inject user's data into my application, I hope you can help me but the most important is that I understand why it doesn't work.

Here are my several files :

I have two actions, one for the request and the other for the response:

actions/index.js

export const REQUEST_CONNECTED_USER = 'REQUEST_CONNECTED_USER';
export const RECEIVE_CONNECTED_USER = 'RECEIVE_CONNECTED_USER';
function requestConnectedUser(){
    return {
        type: REQUEST_CONNECTED_USER
    }
}
function receiveConnectedUser(user){
    return {
        type: RECEIVE_CONNECTED_USER,
        user:user,
        receivedAt: Date.now()
    }
}
export function fetchConnectedUser(){
    return function(dispatch) {
        dispatch(requestConnectedUser());

        return fetch(`http://local.particeep.com:9000/fake-user`)
            .then(response =>
                response.json()
            )
            .then(json =>
                dispatch(receiveConnectedUser(json))
            )

    }
}

reducer/index.js

import { REQUEST_CONNECTED_USER, RECEIVE_CONNECTED_USER } from '../actions
function connectedUser(state= {
}, action){
    switch (action.type){
        case REQUEST_CONNECTED_USER:
            return Object.assign({}, state, {
                isFetching: true
            });
        case RECEIVE_CONNECTED_USER:
            return Object.assign({}, state, {
                user: action.user,
                isFetching: false
            });
        default:
            return state;
    }
}

And I have finally my container element, that I have called Profile.js

import React from 'react';
import { fetchConnectedUser } from '../actions';
import { connect } from 'react-redux';

class Profile extends React.Component{
    constructor(props){
        super(props);
    }

    componentDidMount() {
        const { dispatch } = this.props;
        dispatch(fetchConnectedUser());
    }

    render(){
        const { user, isFetching} = this.props;

        console.log("Props log :", this.props);
        return  (

            <DashboardContent>

                {isFetching &&
                <div>
                    Is fetching
                </div>
                }

                {!isFetching &&
                    <div>
                        Call component here and pass user data as props
                    </div>
                }
            </DashboardContent>
        )
    }
}

function mapStateToProps(state) {

    const {isFetching, user: connectedUser } = connectedUser || { isFetching: true, user: []}

    return {
        isFetching,
        user: state.connectedUser
    }
}


export default connect(mapStateToProps)(Profile)

In the code above, I always have the Is Fetching paragraph being display, but even when I remove it, I cannot access to user data. I think I have the beginning of something because when I console.log I can see my actions being dispatched and the data being added to the state, but I think I am missing something in the link communication with this data to the UI Component. Am I on the good way or do I have a lot of things to refactor ? Any help would be very helpful !

Upvotes: 2

Views: 337

Answers (1)

kjonsson
kjonsson

Reputation: 2799

Seeing as you are immediately fetching the data I allow myself to assume that isFetching may be true at beginning. Add an initial state to your reducer

state = { isFetching: true, user: null }

Then assuming you setup the reducer correctly:

function mapStateToProps(state) {

    const {isFetching, user } = state.connectedUser

    return {
        isFetching,
        user
    }
}

Hope this works, feels clean-ish.

Upvotes: 1

Related Questions