1

使用电极,我注意到这种奇怪的行为 -

当我在页面完全加载所有 api 调用和数据后查看页面源时,我只能查看静态内容,例如超链接、标题、页脚链接等。

我创建了一个自定义令牌处理程序,它检查context对象并填充index.html. 因此,无论何时,我console.log(context.user.content)只记录静态数据,例如超链接、标题、页脚链接。

我想这是问题所在,但我无法理解为什么电极无法识别动态呈现的内容。

令牌处理程序.js 文件

import Helmet from 'react-helmet';

const emptyTitleRegex = /<title[^>]*><\/title>/;

module.exports = function setup(options) {
  // console.log({ options });
  return {
    INITIALIZE: context => {
      context.user.helmet = Helmet.renderStatic();
    },
    PAGE_TITLE: context => {
      const helmet = context.user.helmet;
      const helmetTitleScript = helmet.title.toString();
      const helmetTitleEmpty = helmetTitleScript.match(emptyTitleRegex);

      return helmetTitleEmpty ? `<title>${options.routeOptions.pageTitle}</title>` : helmetTitleScript;
    },
    REACT_HELMET_SCRIPTS: context => {
      const scriptsFromHelmet = ["link", "style", "script", "noscript"]
        .map(tagName => context.user.helmet[tagName].toString())
        .join("");
      return `<!--scripts from helmet-->${scriptsFromHelmet}`;
    },
    META_TAGS: context => {
      console.log(context,'123') //this is where I am checking
      return context.user.helmet.meta.toString();
    }
  };
};

默认.js

module.exports = {
  port: portFromEnv() || "3000",
  webapp: {
    module: "electrode-react-webapp/lib/express",
    options: {
      prodBundleBase: '/buy-used-car/js/',
      insertTokenIds: false,
      htmlFile: "./{{env.APP_SRC_DIR}}/client/index.html",
      paths: {
        "*": {
          content: {
            module: "./{{env.APP_SRC_DIR}}/server/views/index-view"
          },
        }
      },
      serverSideRendering: true,
      tokenHandler: "./{{env.APP_SRC_DIR}}/server/token-handler"
    }
  }
};

任何线索任何人?

编辑 1

但是,将呈现在元标记上发生的任何后续更新。我不确定这是电极允许的还是react-helmet.

编辑 2

SSR 在电极中启用。

4

1 回答 1

0

在深入研究文档后,意识到存在轻微的误解。因此,如果数据需要存在于页面源中,则需要由服务器进行预渲染。

为什么我问这个问题的时候没有显示?因为,由于页面源仅呈现静态内容,因此正在运行时评估数据。

Electrode 已经提供了一个抽象,每个被渲染的组件都有一个加载预取数据的选项。这里的问题是,您必须评估运行时需要存在的所有数据,因为更多数据与页面加载时间成正比(因为服务器不会解析,除非您所依赖的 api 返回成功或失败 )

在实现方面,每个路由都有一个调用参数,该参数init-top在页面加载之前执行。

const routes = [
  {
    path: "/",
    component: withRouter(Root),
    init: "./init-top",
    routes: [
      {
        path: "/",
        exact: true,
        component: Home,
        init: "./init-home"
      },

在 中init-home,您可以在以下行中定义它 -

import reducer from "../../client/reducers";
const initNumber = async () => {
  const value = await new Promise(resolve => setTimeout(() => resolve(123), 2000));
  return { value };
};
export default async function initTop() {
  return {
    reducer,
    initialState: {
      checkBox: { checked: false },
      number: await initNumber(),
      username: { value: "" },
      textarea: { value: "" },
      selectedOption: { value: "0-13" }
    }
  };
}

因此,现在每当您加载组件时,它都会加载initialState返回的thisinit-home

我会在这里发布它,以防有人被卡住。

于 2019-03-31T10:31:32.717 回答