TypeScript 2、React JS 和 Express 服务器端渲染问题

Posted

技术标签:

【中文标题】TypeScript 2、React JS 和 Express 服务器端渲染问题【英文标题】:TypeScript 2, React JS and Express Server-side Rendering Issue 【发布时间】:2017-04-14 02:35:32 【问题描述】:

所以...

我遇到了问题...

Invariant Violation:元素类型无效:预期为字符串(对于内置组件)或类/函数(对于复合组件),但得到:对象。

...关于“导出默认值”,我多次找到相同的response。希望我的问题的解决方案是关于我的 TypeScript 编译、ECMA 版本兼容性等的简单方法,但感谢任何帮助。

tsconfig.json


  "compilerOptions": 
    "jsx": "react",
    "outDir": "dist"
  ,
  "include": [
    "src/**/*"
  ]

我意识到我没有指定“目标”,所以 tsc 默认为“es3”,我认为这是最好的向后兼容性。我尝试更新到“es5”,但这并没有解决我的问题。

server.ts

this.app.set("views", path.join(__dirname, "views"))
this.app.set("view engine", "js")

var engines = require('consolidate')
this.app.engine('js', engines.react)

由于我在 tsconfig.json 中为“jsx”属性指定了“react”,所以我编译的文件将是 .js,但仍将包含 React.createElement 等调用,因此我指定了我的快速视图引擎让 JS 文件使用整合项目的反应引擎。以前我使用的是express-react-views,在这里对我的策略的任何输入都会有所帮助。

index.tsx

import * as React from 'react'

interface HelloMessageProps 
    name: string


class HelloMessage extends React.Component<HelloMessageProps, > 
  render() 
    return <div>Hello this.props.name!</div>;
  

index.ts

// ...
// routing code
// ...
let options: Object = 
    "name": "World"
;

res.render("index", options);

...非常感谢任何帮助!

【问题讨论】:

【参考方案1】:

发现我的问题是我实际上不想“渲染”视图文件(html、jade 等)。所以我不需要 express-react-views 也不需要合并,我可以删除我的代码...

this.app.set("views", path.join(__dirname, "views"))
this.app.set("view engine", "js")

var engines = require('consolidate')
this.app.engine('js', engines.react)

...并将我的 index.ts 文件更新为...

// ...
// routing code
// ...
let options: Object = 
    "name": "World"
;

const components = require('../../components')
const HelloMessage = React.createFactory(components.HelloMessage)

const ReactDOM = require('react-dom/server')
res.send(ReactDOM.renderToString(HelloMessage(options)));

...这里的关键是使用 ReactDOM 的 renderToString 方法执行“渲染”(即转换为最终的 HTML),并简单地将输出发送到响应 (res.send(...)) 而不是尝试渲染它(res.render(...))。

【讨论】:

以上是关于TypeScript 2、React JS 和 Express 服务器端渲染问题的主要内容,如果未能解决你的问题,请参考以下文章

如何将 React 路由器功能转换为 Typescript?

在 React Js 中的 TypeScript 中创建一个包含 2 列、2 行和 3 个单元格的网格

React.js 和 Typescript 返回获取 API 响应的类型?

参数 'e' 隐含了一个 'any' 类型 React TypeScript

Storybook 在 React、Next.JS、Typescript 项目中找不到组件

尝试使用 Typescript 在简单的 React 表单组件中使用 handleChange。难以访问 e.target.value