Reputation: 323
I'm learning react with redux and I want to achieve something like this:
When I go to this url:
some_url/posts/1
I want to fetch from my server some data and then show it on page.
However it throws null pointer exception because it takes some time to get data.
I did something like this but it doesnt looks well, what is the proper way to prevent this null pointer exception and wait untill data will arrive?
Inside my component:
componentWillMount() {
this.props.fetchPost(
parseInt(this.props.match.params.postId));
}
render(){
return(
<div>
{post.title}
</div>
)};
My action creator:
export function fetchPost(postId){
const request = axios.get(`${ROOT_URL}/posts${postId}`);
return {
type: FETCH_POST,
payload: request
};
}
And reducer, here I just filled state with empty template of object which server is providing. Without this I got NullPointerException.
import { FETCH_POST } from "../actions";
export default function(state = {id: 0, title: "", infos: [{id: 0, content: "", authorId: 0}]}, action){
switch(action.type){
case FETCH_POST:
return action.payload;
}
return state;
}
What is the proper way to wait until data will arrive?
Upvotes: 2
Views: 486
Reputation: 2889
Actions in redux should always return a plain JS object which should have a mandatory type
property.
When you are executing async code in the action creator, the returned object is no longer a plain JS object.
If you have to use redux
then you would have to use a middleware like redux-thunk
.
https://github.com/reduxjs/redux-thunk
However, middlewares are advanced topic in react & redux.
If you just want to fetch some data from your api, you can do that in plain react. But for using redux flow, use a middleware. You can also do it without a middleware, but that is not the recommended approach.
Upvotes: 1
Reputation: 1938
Axios is using Promise to handle http responses aynshcronously.
Promise based HTTP client for the browser and node.js
So when you return your request object, it is currently not resolved. I think you need to refactor a little bit your code with something looking like:
function fetchPost(postId) {
return axios.get(`${ROOT_URL}/posts${postId}`);
}
// And your action creator
function updateContent(payload) {
return {
type: UPDATE_CONTENT,
payload: payload,
}
}
And call that in your component:
componentWillMount() {
fetchPost(parseInt(this.props.match.params.postId)).then(this.props.updateContent);
}
By the way, there are plenty of ways to do this, I think you should read axios documentation and pick the one you prefer and the one matching your application requirements.
Upvotes: 1