【问题标题】:redux store out of sync store().getState() with state from redux loggerredux store 与来自 redux logger 的状态不同步 store().getState()
【发布时间】:2018-02-10 15:07:59
【问题描述】:

我在 SSR react 应用程序中遇到了 redux 存储问题。一切正常,在服务器上创建的 initialState 由客户端上的 window.initialState 接收。当我想在我的 App.js 中通过 store().getState 获取当前商店时出现问题

createStore.js

const configureStore = preloadedState => {

    const store = createStore(
        rootReducer,
        preloadedState || global.__initialData__,
        applyMiddleware(
            promiseMiddleware(),
            thunk,
            // logger
        )
    );

    if (module.hot) {
        // Enable Webpack hot module replacement for reducers
        module.hot.accept('./reducers', () => {
            const nextRootReducer = require('./reducers/index');
            store.replaceReducer(nextRootReducer);
        });
    }
    return store;
}

export default configureStore;

server.js

const stores = createStore( reducers );
stores.dispatch(setLang( serve_lang )); // 'pl'
global.__initialData__ = stores.getState();
let initialDatas = stores.getState();
const store = configureStore( initialDatas );
...
<html>
<script>window.__initialData__ = ${serialize(initialDatas)}</script>
...

client.js

 const store = configureStore(window.__initialData__);

    hydrate(
      <Provider store={store} key={Math.random()}>
        <BrowserRouter>
          <App />
        </BrowserRouter>
    </Provider>,
  document.getElementById('root')
    );

    if (module.hot) {
      module.hot.accept();
    }

在我的 App.js 中,我想通过

获得我当前的商店
import store from 'configureStore'l
store().getState();

当我在 App.js 中执行 store.getState() 时,我总是有 initialState

【问题讨论】:

    标签: javascript reactjs redux server-side-rendering


    【解决方案1】:

    当我在 App.js 中执行 store.getState() 时,我总是有 initialState

    您正在创建一个新的商店实例。这不会被修改,因为您的其余组件使用您在 client.js 中创建的另一个组件

    import store from 'configureStore'l
    store().getState(); // this is new store not the one you have passed to Provider
    

    您可以做的是使用属性将第一个商店实例传递给 client.js 内的 App。

    const store = configureStore(window.__initialData__);
    
    hydrate(
      <Provider store={store} key={Math.random()}>
        <BrowserRouter>
          <App store={store}/>
        </BrowserRouter>
    </Provider>,
    document.getElementById('root')
    

    或者通过上下文访问它(Provider 实际上将它的存储放到上下文中,以便内部“连接”的组件可以访问它)。你可以在这里阅读上下文。 Docs.

    【讨论】:

    • 我将商店传递给 App,但是当我执行 store().getState() 时,我仍然有 initialState :/
    • @krystianj 你不应该做store().getState() 你的store 函数会在每次调用时返回新的存储。相反,您应该使用this.props.storethis.context.store。您还可以在调用this.props.store.getState() 的确切时间获得商店状态,它可能会在以后更改。因此,您阅读状态的准确时间很重要。
    • 好的 - 现在this.props.store.getState() 工作,但我现在如何在客户端使用商店?我可以使用调度吗?
    • 可以用 initialState 在客户端创建新的商店吗?所以我们可以在客户端调度商店并通过 store().getState() 访问应用程序中的整个组件,因为现在当我使用 store().getState() 时,我创建了新商店...
    • 我不确定我是否理解您的问题。每当 ssr 服务器接受新请求时,它都会创建新存储,将其传递给组件,以某种方式填充它,然后将其序列化为 window.__initialData__ 并将 html 字符串发送回客户端。然后,客户端使用序列化数据创建新存储并将其传递给组件。因此,您在序列化之前存储在服务器上的所有内容都将在客户端上可用。如果你在序列化之后添加一些东西,客户端将看不到它。如果您的客户端更改了某些服务器将看不到的内容(过程是单向的)。
    猜你喜欢
    • 1970-01-01
    • 2016-12-25
    • 1970-01-01
    • 1970-01-01
    • 2019-02-26
    • 2020-10-21
    • 1970-01-01
    • 1970-01-01
    • 2020-09-15
    相关资源
    最近更新 更多