Reputation: 369
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
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