TypeScript 2、React JS 和 Express 服务器端渲染问题
TypeScript 2, React JS and Express Server-side Rendering Issue
所以...
我 运行 关注这个问题...
Invariant Violation: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.
...关于 "export default",我多次发现相同的 。希望我的问题的解决方案在我的 TypeScript 编译、ECMA 版本兼容性等方面很简单,但我们将不胜感激。
tsconfig.json
{
"compilerOptions": {
"jsx": "react",
"outDir": "dist"
},
"include": [
"src/**/*"
]
}
我意识到我没有指定 "target" 所以 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);
...非常感谢任何帮助!
发现我的问题是我试图 "render" 查看文件(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 方法执行 "rendering"(即转换为最终的 HTML)并简单地将输出发送到响应(res.send(...)) 而不是尝试渲染它 (res.render(...)).
所以...
我 运行 关注这个问题...
Invariant Violation: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.
...关于 "export default",我多次发现相同的
tsconfig.json
{
"compilerOptions": {
"jsx": "react",
"outDir": "dist"
},
"include": [
"src/**/*"
]
}
我意识到我没有指定 "target" 所以 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);
...非常感谢任何帮助!
发现我的问题是我试图 "render" 查看文件(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 方法执行 "rendering"(即转换为最终的 HTML)并简单地将输出发送到响应(res.send(...)) 而不是尝试渲染它 (res.render(...)).