在商店重新水化后,无法使用redux-persist获取持久状态的值

时间:2017-10-04 03:35:48

标签: javascript reactjs redux persist

所以,让我说我有一个Home组件,它只是执行api调用从服务器获取所有的homeworks:

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);

页面刷新,当然它会因为componentDidMount()生命周期而执行api调用。现在,我想更改它并使用persisted使用redux-persist数据,这样就可以避免每当页面刷新时都会调用api ...

我正在使用redux-persist库.. 这是我的app组件与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;

我知道resux persist正在运行,因为redux记录器 snapshot of redux logger

现在,我如何获得持久状态的值?我尝试制作另一个减速器: persistReducer     从&#39; ../ actions / types&#39;;

导入{PERSIST}
export default (state = [], action) => {
    switch(action.type) {
        case PERSIST:
            return { ...state, persistState: action.payload }
        default:
            return state;   
    }
};

并将其添加到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
});

在我的Home组件中,我使用

访问它
componentWillReceiveProps(nextProps) {

    if(nextProps.persist.persistState) {
        console.log(nextProps.persist.persistState.home_works.home_works)   
    }
}

并正确获取值:enter image description here

那么如何正确地做到这一点?

1 个答案:

答案 0 :(得分:1)

旁注,但如果你颠倒了if语句中的逻辑,你可以稍微清理一下代码:

这样:

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>
    }
}

可以成为:

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} />)
}
  1. 对于只有一个表达式的if语句,您可以省略{}
  2. 0是一个假值,因此home_works.length === 0!home_works都返回true
  3. 如果函数只返回一个表达式(几乎在所有情况下),则可以使用带有胖箭头=>语法的隐式返回
  4. 例如,home_works.map(() => something())home_works.map(() => { return something() })相同。如果它只返回一个JSX元素(例如div或一个组件),也可以这样使用JSX。

    我刚刚向您展示的代码是有效的,因为React正在渲染HomeWorks,它首先检查是否存在错误 - 如果是,则从渲染函数返回 - 然后,它会检查它是否正在加载或者{{1是假的 - 如果是这样,从函数返回 - 最后,它继续并呈现作业行列表。