I am trying to create a simple message wall with a <PostList />
container which displays a list of <Post />
components.
{posts.map(function (post: any) {
return <Post key={post.postid} post={post} />;
})}
I pass in a single post to the Post
component which has a <Avatar />
component that displays the users profile_pic inside it otherwise it displays a spinner.
My question is how would I allow the components to display on screen and once the image is loaded replace the spinner with the retrieved image?
I currently have the following Reducers and Actions:
User Reducer:
export default function(state = INITIAL_STATE, action : any){
switch(action.type){
case FETCH_USER_LOADING:
return Object.assign({}, state, {isLoading: true});
case FETCH_USER_DONE:
return Object.assign({}, state, {users: state.users.concat(action.payload)});
}
return state;
}
User Actions:
export function fetchUser(id: any) {
return function (dispatch: any) {
dispatch({ type: FETCH_USER_LOADING });
return axios.get(`${ROOT_URL}/users/${id}`, {
headers: { token: localStorage.getItem('token') }
})
.then(function (response) {
dispatch({type: FETCH_USER_DONE, payload: response.data});
return response.data
})
}
}
Redux Async Data Flow Just like with a normal action, we first need to handle a user event in the application, such as a click on a button. Then, we call dispatch() , and pass in something, whether it be a plain action object, a function, or some other value that a middleware can look for.
To load images faster in a React application you can use one of the following techniques: Use lazy loading method --> The image loads only when the user scrolls to it. Use blur technique --> This loads the images in low resolution initially before the original load. Use JPEG-XR and WebP instead of PNG, JPG etc.
Plenty of ways to do it.
One of which is to write your own component, where, a newly loaded image prompts a redraw in componentDidMount
. Here's the full source code of a lazy image that you can use in your own project:
export default class LazyImage extends React.Component {
constructor(props) {
super(props);
this.state = {
loaded: false,
error: false
};
}
componentDidMount() {
const img = new Image();
img.onload = () => {
this.setState({
loaded: true
});
};
img.onerror = () => {
this.setState({
error: true
});
};
img.src = this.props.src;
}
render() {
if (this.state.error) {
return <img
className={this.props.className}
style={this.props.style}
src={this.props.unloadedSrc}
alt={this.props.alt} />
} else if (!this.state.loaded) {
return <img
className={this.props.className}
style={this.props.style}
src={this.props.unloadedSrc}
alt={this.props.alt} />
}
return <img
className={this.props.className}
style={this.props.style}
src={this.props.src}
alt={this.props.alt} />
}
}
Which you would then use like so:
<LazyImage unloadedSrc={unloadedSrc} src={src} />
And then, you have the option of using a plethora of components that you can find just by googling the terms:
Or any similar search term variety, thereof. My favourite component is react-imageloader
.
I hope this helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With