7

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

创建商店:

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

Finaly 启动应用会话:

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 做同样的事情?

使用新的上下文我很舒服,我只想了解商店、本地存储、订阅。因此,即使用户离开应用程序,状态也会保持不变。

4

2 回答 2

4

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

最后,在您的 pages/HomePage/index.js 中,您可以 import { Provider } from './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>
      );
    }
  }
于 2018-08-07T12:48:31.613 回答
2

第一件事

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

  • react 的 Context API 甚至不是 react 的一个新特性,它一直都在那里,只是换了一张新面孔。这是一种无需道具钻孔即可将数据传递给孩子的方法。

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

如果您Redux已经在使用,我认为不使用react-redux.

您可以在这篇文章中阅读有关差异的更多详细信息(完全公开,我是作者)。

于 2018-08-07T16:27:34.077 回答