【问题标题】:With React / Redux, how do I dynamically pre-load state?使用 React / Redux,我如何动态预加载状态?
【发布时间】:2017-08-22 07:07:53
【问题描述】:

我很难使用 React / Redux 预加载状态。

在将其标记为重复之前,我已经阅读了以下内容:

这是我的场景:

  • 我正在使用 Node + React + Redux。
  • 当我从服务器加载页面时,我从数据库加载User 对象。我需要这个User 对象处于没有往返服务器的状态
  • 因为User 对象是动态的,所以我不能将它放在包中。
  • 使用服务器渲染。

我的问题:

我最初如何将用户对象从服务器加载到我在客户端的存储中?

this answer,丹·阿布拉莫夫说:

在客户端上,您可以从 全局变量 中读取它,并使用它创建客户端存储实例。换句话说,您永远不必手动创建 initialState——您应该使用 store.getState() 在服务器上获取它,将其传递给客户端,然后使用它创建一个 store。

所以,我假设,全局变量,他的意思是这样的:

// Here, window._initialState.user is being sent to the client in a <script/> tag.
const store = createStore(reducers, { user: window._initialState.user);

上述可能有效,问题是我没有信心这实际上是一个好习惯,因为我在互联网上没有找到任何示例关于它。

那么,这是正确的做法吗?有没有更好/更推荐的方法?

【问题讨论】:

  • FWIW,这是我们公司的标准做法,我们已经编写了一堆 redux 应用程序。我们还进行服务器端渲染并通过服务器端存储实例生成该状态,但即使没有它也应该可以工作。
  • @RicoKahler,谢谢。它在那里,我没有看到它。如果您想添加答案,我会接受。否则我会用你的评论回答我自己的问题。

标签: javascript reactjs redux


【解决方案1】:

这是直接取自redux recipes page:

为了传递状态,我们添加一个标签,将 preloadedState 附加到window.__PRELOADED_STATE__

function renderFullPage(html, preloadedState) {
return `
    <!doctype html>
    <html>
    <head>
        <title>Redux Universal Example</title>
    </head>
    <body>
        <div id="root">${html}</div>
        <script>
        // WARNING: See the following for security issues around embedding JSON in HTML:
        // http://redux.js.org/docs/recipes/ServerRendering.html#security-considerations
        window.__PRELOADED_STATE__ = ${JSON.stringify(preloadedState).replace(/</g, '\\u003c')}
        </script>
        <script src="/static/bundle.js"></script>
    </body>
    </html>
    `
}

【讨论】:

    【解决方案2】:

    当我从服务器加载页面时,我从数据库加载用户对象。我需要此 User 对象处于无需往返服务器的状态。

    如果您不是服务器渲染,我认为您应该对服务器进行初始往返。我的看法是,您必须至少对服务器进行两次调用:一次用于可缓存的捆绑包,一次用于数据。即使您正在加载一个脚本,该脚本将设置一个具有某些初始状态的全局变量,您仍然需要进行另一个调用以获取正确的捆绑包?我可能会误解,但我看不出以您描述的方式设置初始状态有什么好处。如果你不是服务器渲染,那么可能一个普通的 ole RESTful API 和 SPA 更简单。

    我最初如何将用户对象从服务器加载到我在客户端的存储中?

    我的建议是只在服务器上进行第一次往返并等待 fetch 承诺解决,然后创建您的商店并呈现应用程序。

    fetch('http://example.com/something').then(data => data.json()).then(initalState => {
        render(
            <Provider store={/*stored created with initalState*/}>
                <App />
            </Provider>,
            document.getElementById('app')
        )
    });
    

    再次,我可能误解了您的问题/架构,但这只是我的两分钱。祝你好运!

    【讨论】:

    • 您的评论正是我想要的。添加它作为答案,我会接受它。
    猜你喜欢
    • 2016-02-28
    • 1970-01-01
    • 2021-03-26
    • 2019-07-19
    • 2018-10-03
    • 2019-10-21
    • 1970-01-01
    • 2018-05-29
    • 2019-08-09
    相关资源
    最近更新 更多