Simon Breton Simon Breton - 3 months ago 21
React JSX Question

Component structure to handle Async Action with Redux-thunk ?

After a bit of trial and error I finally manage to get my action creator working properly and passing the data I wanted into my redux store. Until now I've been dispatching it "manually" like this

store.dispatch(fetchTest());
but It would be great if could use these data into a component.

So here is my action creator :

export const fetchTest = () => (dispatch) => {
dispatch({
type: 'FETCH_DATA_REQUEST',
isFetching:true,
error:null
});
return axios.get('http://localhost:3000/authors')
.then(data => {
dispatch({
type: 'FETCH_DATA_SUCCESS',
isFetching:false,
data: data
});
})
.catch(err => {
dispatch({
ype: 'FETCH_DATA_FAILURE',
isFetching:false,
error:err
});
console.error("Failure: ", err);
});
};


Here is my reducer :

const initialState = {data:null,isFetching: false,error:null};
export const ThunkData = (state = initialState, action)=>{
switch (action.type) {
case 'FETCH_DATA_REQUEST':
case 'FETCH_DATA_FAILURE':
return { ...state, isFetching: action.isFetching, error: action.error };

case 'FETCH_DATA_SUCCESS':
return Object.assign({}, state, {data: action.data, isFetching: action.isFetching,
error: null });
default:return state;

}
};


So far everything is working properly when using
store.dispatch(fetchTest());
.

Based on this example I tried to build the following component :

class asyncL extends React.Component {
constructor(props) {
super(props);
}
componentWillMount() {
this.props.fetchTest(this.props.thunkData)
// got an error here : "fetchTest is not a function"
}
render() {
if (this.props.isFetching) {
return console.log("fetching!")
}else if (this.props.error) {
return <div>ERROR {this.props.error}</div>
}else {
return <p>{ this.props.data }</p>
}
}
}

const mapStateToProps = (state) => {
return {
isFetching: state.ThunkData.isFetching,
data: state.ThunkData.data.data,
error: state.ThunkData.error,
};
};


const AsyncList = connect(mapStateToProps)(asyncL);
export default AsyncList


It doesn't work, I have an error on the
componentWillMount()
and probably somewhere else.

Also my data structure is kind of weird. To actually get to the data array I have to do
state.ThunkData.data.data
. The first data object is full of useless stuff like
request
,
headers
, etc...

So how should I write this component so I can at least passed the Async data into a console.log.

Thanks.

Answer

You need to mapDispatchToProps as well.

import { fetchTest } from './myFetchActionFileHere';
import { bindActionCreators } from 'redux';

function mapDispatchToProps(dispatch) {
  return {
    fetchTest: bindActionCreators(fetchTest, dispatch)
  };
}

const AsyncList = connect(mapStateToProps, mapDispatchToProps)(asyncL);
export default AsyncList

documentation link: http://redux.js.org/docs/api/bindActionCreators.html