React:Redux在本地存储中的持久性

时间:2018-07-09 02:43:45

标签: javascript reactjs redux

我正在尝试使用Redux将数据持久化到本地存储。我刚做了一个字母数组。每当我使用onclick侦听器单击该元素时,每次都会看到控制台日志语句带有随机字母,但是UI不会像setState()那样重新呈现,直到刷新页面为止。我在这里想念什么?

src/index.js

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';
import {createStore} from 'redux';
import myApp from './reducers';

import {loadState, saveState} from './localStorage'


const persistedState = loadState();

const store = createStore(
    myApp,
    persistedState
);

store.subscribe(() => {
    saveState(store.getState());
});

function render () {
    ReactDOM.render(<App store={store}/>, document.getElementById('root'));
    registerServiceWorker();
}

render();

src/app.js

import React, { Component } from 'react';
import './App.css';
import { switchName } from './actions'

class App extends Component {

  constructor(props) {
    super(props);
    this.store = this.props.store;
  }

  handleChangeName = () => {
    let array = ["a","b","c","d","e","f","g","h","i"];
    const data = array[Math.floor(Math.random() * array.length)];
    this.store.dispatch(switchName(data));
  }



  render() {
    return (
      <div className="App">

        <p className="ntro" onClick = {this.handleChangeName} >
          Letter:  {this.store.getState().name}
        </p>
      </div>
    );
  }
}

export default App;

src/localstorage.js

export const loadState = () => {
    try {
        const serializedState = localStorage.getItem('state');
        if (serializedState === null) {
            console.log("serialzed state null")

            return undefined;
        }
        return JSON.parse(serializedState);
    } catch (err) {
        return undefined;
    }
};


export const saveState = (state) => {
    try {
        console.log(state)
        const serializedState = JSON.stringify(state);
        localStorage.setItem('state', serializedState);

    } catch (err) {};
}   

src/reducers.js

const initialState = {
    name: "nada"
}

export default (state = initialState, action) => {
    switch (action.type) {
        case "SWITCH_NAME":
            return Object.assign({}, state,{
                name: action.data
            })

        default:
            return state

    }
}

1 个答案:

答案 0 :(得分:1)

您的App组件未订阅商店,因此当商店更改时它不会重新呈现(即,它将仅使用从name返回的第一个store.getState()值< / p>

要解决此问题,您可以使用react-reduxconnect到商店,而不用将其作为道具。

src/index.js

import { Provider } from 'react-redux';

// ...

function render () {
    ReactDOM.render(<Provider store={store}><App store={store}/></Provider>, document.getElementById('root'));
    registerServiceWorker();
}

src/app.js

import { connect } from 'react-redux'

// ...

class App extends Component {

  handleChangeName = () => {
    let array = ["a","b","c","d","e","f","g","h","i"];
    const data = array[Math.floor(Math.random() * array.length)];
    this.props.switchName(data);
  }

  render() {
    return (
      <div className="App">

        <p className="ntro" onClick = {this.handleChangeName} >
          Letter:  {this.props.name}
        </p>
      </div>
    );
  }
}

// note that `store` is no longer used inside the `App` component

const mapState = state => ({ state.name });
const actions = { switchName };

export default connect(mapState, actions)(App);

或者,您可以在render()的{​​{1}}回调中添加一个subscribe调用

src/index.js

尽管您可能想通过// ... store.subscribe(() => { saveState(store.getState()); render(); }); function render () { ReactDOM.render(<App store={store}/>, document.getElementById('root')); registerServiceWorker(); } render(); 调用来做其他事情。


旁注:您是否尝试过redux-persist