Reputation: 406
So let's say I have a Home Component which it just perform api call to fetch all homeworks from the server:
import React, { Component } from 'react';
import { fetchHomeWorks } from '../actions';
import HomeWorkRow from '../component/HomeWorkRow';
class Home extends Component {
componentDidMount() {
this.props.fetchHomeWorks()
}
renderHomeWorks() {
const { home_works, error, loading } = this.props;
if(!error) {
if(!loading){
if(home_works.length >=1) {
return home_works.map(home_work => {
return <HomeworkRow key={uuid()} home_work={home_work} />
})
}
else
return <p className="pt-card col-xs-12 col-xs-offset-1 content"> No Task Yet :)</p>
}
else
return <p>Loading...</p>
}
}
render() {
return (
<Layout>
{ this.props.renderHomeworks() }
</Layout>
);
}
}
const mapStateToProps = ({ home_work, persist }) => {
return {
home_works: home_work.home_works,
persist:
};
};
export default connect(mapStateToProps, { fetchHomeWorks })(Home);
on page refresh, Of course it will perform the api call because of componentDidMount() lifecycle.. Now, I want to change it and use the persisted
data using redux-persist
so it will avoid the api call whenever page is refreshed...
I am using the redux-persist
library..
Here is my app component with redux persist():
import React, { Component } from 'react';
import { Provider } from 'react-redux';
import {
BrowserRouter as Router,
Route,
} from 'react-router-dom';
import { compose, createStore, applyMiddleware } from 'redux';
import {persistStore, autoRehydrate} from 'redux-persist';
import thunk from 'redux-thunk';
import logger from 'redux-logger';
import rootReducer from './reducers/';
class App extends Component {
render() {
const store = createStore(rootReducer, {}, compose(applyMiddleware(thunk, logger), autoRehydrate()));
persistStore(store);
return (
<Provider store={store}>
<Router>
<div>
<Route exact path="/" component={LoginForm} />
// ... some routes which doesnt matter
</div>
</Router>
</Provider>
);
}
}
export default App;
I know the resux persist is working because of the redux logger
Now, how do I get the value of the persisted state? I tried making another reducer:
persistReducer
import { PERSIST } from '../actions/types';
export default (state = [], action) => {
switch(action.type) {
case PERSIST:
return { ...state, persistState: action.payload }
default:
return state;
}
};
and adding it in rootReducer
:
import { reducer as formReducer } from 'redux-form'
import { combineReducers } from 'redux';
import homeWorkReducer from './userReducer';
import persistReducer from './persistReducer';
export default combineReducers({
home_works: homeWorkReducer,
form: formReducer,
persist: persistReducer
});
and in my Home
component, i access it using
componentWillReceiveProps(nextProps) {
if(nextProps.persist.persistState) {
console.log(nextProps.persist.persistState.home_works.home_works)
}
}
and getting the values correctly:
so how to do it correctly?
Upvotes: 2
Views: 1779
Reputation: 17132
Side note, but you can clean up the code a bit if you reverse the logic in your if statements:
this:
renderHomeWorks() {
const { home_works, error, loading } = this.props;
if(!error) {
if(!loading){
if(home_works.length >=1) {
return home_works.map(home_work => {
return <HomeworkRow key={uuid()} home_work={home_work} />
})
}
else
return <p className="pt-card col-xs-12 col-xs-offset-1 content"> No Task Yet :)</p>
}
else
return <p>Loading...</p>
}
}
can become:
renderHomeWorks() {
const { home_works, error, loading } = this.props;
if (error) return <p>Loading...</p>
if (loading || !home_works) return <p className="pt-card col-xs-12 col-xs-offset-1 content"> No Task Yet :)</p>
return home_works.map(home_work => <HomeworkRow key={uuid()} home_work={home_work} />)
}
{
and }
for if statements that only have one expression.0
is a falsy value, so home_works.length === 0
and !home_works
both return true=>
syntax if the function only returns one expression (in almost all cases)For example, home_works.map(() => something())
is the same as home_works.map(() => { return something() })
. You can use JSX this way also if it only returns one JSX element (such as a div, or one component).
This code I just showed you works because as React is rendering HomeWorks, it first checks if there is an error -- if so, returns from the render function -- then, it checks if it is loading or if home_works
is falsy -- if so, returns from the function -- and finally, it goes ahead and renders the list of homework rows.
Upvotes: 1