新的React Context API + LocalStorage +订阅(替换为Redux)

时间:2018-08-03 12:15:34

标签: reactjs redux local-storage state react-context

我有一个使用Redux的应用程序。存储全局状态,如下所示:

创建商店:

import {createStore, applyMiddleware} from 'redux';
import rootReducer from '../reducers';
import thunk from 'redux-thunk';

const configureStore = initialState => {
  return createStore(
    rootReducer,
    initialState,
    applyMiddleware(thunk)
  );
};

export default configureStore;

处理本地存储

  const storageName = 'xxxState';
  export const loadState = () => {
  try {
    const serializedState = localStorage.getItem(storageName);
    if (serializedState === null) {
      return undefined;
    }
    return JSON.parse(serializedState);
  } catch(err) {
    return undefined;
  }
};

export const saveState = state => {
  try {
    const serializedState = JSON.stringify(state);
    localStorage.setItem(storageName, serializedState);
  } catch(err) {
    throw err;
  }
};

最后开始应用会话:

import React from 'react';
import ReactDOM from 'react-dom';
import Start from './start';
import { Provider } from 'react-redux';
import configureStore from './store/configureStore';
import { loadState, saveState } from './store/localStorage';
import throttle from 'lodash/throttle';

const persistedState = loadState();

const store = configureStore(persistedState);
store.subscribe(throttle(() => {
  saveState(store.getState());
}, 1000));

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

它完美地工作。所以我的问题是:是否有可能对新的React Context API进行同样的操作?

我对使用新上下文非常满意,我只想了解存储,本地存储和订阅。因此,即使用户离开应用程序,状态也将保持不变。

2 个答案:

答案 0 :(得分:2)

store.js

import React, { Component, createContext } from "react";

export const createStore = store => {
  const Context = createContext();
  let self;
  const setState = (action, state, args) => {
    self.setState(state);
  };
  const actions = Object.keys(store.actions).reduce(
    (accumulator, currentValue) => {
      return {
        ...accumulator,
        [currentValue]: function(...args) {
          let result = store.actions[currentValue](
            { state: self.state, actions: self.value.actions },
            ...args
          );
          if (result) {
            result.then
              ? result.then(result => setState(currentValue, result, args))
              : setState(currentValue, result, args);
          }
        }
      };
    },
    {}
  );
  class Provider extends Component {
    constructor() {
      super();
      this.state = store.initialState;
      self = this;
      this.value = {
        actions,
        state: this.state
      };
    }
    render() {
      if (this.state !== this.value.state) {
        this.value = {
          actions,
          state: this.state
        };
      }
      return (
        <Context.Provider value={this.value}>
          {this.props.children}
        </Context.Provider>
      );
    }
  }
  class Consumer extends Component {
    renderProps = ({ actions, state }) => {
      // const { mapStateToProps, mapDispatchToProps } = this.props;
      return this.props.children({
        state: state,
        actions: actions
      });
    };
    render() {
      return <Context.Consumer>{this.renderProps}</Context.Consumer>;
    }
  }
  const connect = (mapStateToProps, mapDispatchToProps) => WrappedComponent => {
    return (
      <Consumer
        mapStateToProps={mapStateToProps}
        mapDispatchToProps={mapDispatchToProps}
      >
        {injectedProps => (
          <WrappedComponent {...injectedProps} {...this.props} />
        )}
      </Consumer>
    );
  };
  return {
    Provider,
    Consumer,
    connect
  };
};

然后对于每个页面,您都可以执行以下操作和初始存储值

import { createStore } from "@src/store";
import { Actions } from "../actions";
import { storage } from "@helpers/storage";
import constants from "@src/constants";

import { util } from "@src/utils";

function getInitialState() {
  let Id = null;
  if (storage.get(constants.STORAGE_KEY)) {
    let storageObject = storage.get(constants.STORAGE_KEY);
    Id = storageObject["Id"];
    selectedDate = storageObject["selectedDate"];
  }
  return {
    data: null,
    activeTab: "score",
    Id: Id
  };
}
const store = {
  initialState: getInitialState(),
  actions: Actions
};

export const { Provider, Consumer } = createStore(store);

最后在您的页面/HomePage/index.js中 你可以有 从“ ./store”导入{提供者};

render() {
  return (
    <Provider>
     <Homepage user={user} children={children} />
    </Provider>
  );
}

并在您的pages / HomePage / Homepage.js中 你可以拥有

render() {
      return (
        <Consumer>
          {({ state, actions }) => {
            return this.renderChildrens(state, actions);
          }}
        </Consumer>
      );
    }
  }

答案 1 :(得分:0)

第一件事

  • Redux与react无关,它是一个状态管理器。
    它可以帮助您管理保存应用程序状态的大型JavaScript对象。

  • react的Context API甚至不是react的新功能,它一直存在,而且只是一个新面孔。这是一种将数据传递给没有prop drilling的孩子的方法。

我认为您是指react-redux
react-redux是一种抽象,是一种绑定Redux存储以做出反应的方式。 它为您完成了所有商店订阅,并使用Container HOC和connect组件帮助您创建了Provider和消费者。
它还有助于传递存储对象(通过内部的上下文API)。

如果您已经在使用Redux,那么我看不到没有使用react-redux的任何意义。

您可以阅读有关差异In this post的更多详细信息(完整披露,我是作者)。