简体   繁体   English

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

[英]TypeScript 2, React JS and Express Server-side Rendering Issue

SO... 所以...

I am running into the issue... 我遇到了问题...

Invariant Violation: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object. 不变违规:元素类型无效:预期为字符串(对于内置组件)或类/函数(对于复合组件),但得到:对象。

...and I have found the same response multiple times regarding "export default". ...并且我多次发现有关“导出默认值”的相同响应 Hopefully the solution to my problem is something simple regarding my TypeScript compilation, ECMA version compatibility, etc. but any help is appreciated. 希望解决我的问题的方法是有关我的TypeScript编译,ECMA版本兼容性等方面的一些简单操作,但是可以提供任何帮助。

tsconfig.json tsconfig.json

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

I realize I am not specifying a "target" so tsc defaults to "es3" which I thought is best for backwards compatibility. 我意识到我没有指定“目标”,所以tsc默认为“ es3”,我认为这是向后兼容的最佳选择。 I have tried updating to "es5" and this did not fix my issue. 我尝试更新为“ es5”,但这不能解决我的问题。

server.ts 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)

Since I am specifying "react" for the "jsx" property in my tsconfig.json, my compiled files will be .js, but will still contain React.createElement, etc. calls, so I am specifying my express view engine for JS files to use the consolidate project's react engine. 由于我在tsconfig.json中为“ jsx”属性指定“ react”,因此编译后的文件将为.js,但仍包含React.createElement等调用,因此我为JS文件指定了快速视图引擎使用合并项目的反应引擎。 Previously I was using express-react-views , any input on my strategy here would be helpful. 以前,我使用express-react-views ,此处有关我的策略的任何输入都会有所帮助。

index.tsx 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);

...any help is much appreciated! ...任何帮助深表感谢!

Found out that my problem was that I was trying to "render" a view file (html, jade, etc.) when I actually didn't want to. 发现我的问题是当我实际上不想要时,我试图“渲染”视图文件(html,jade等)。 So I don't need express-react-views nor consolidate and I can remove my code... 因此,我不需要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)

...and update my index.ts file to be... ...并将我的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)));

...the key here being to perform the "rendering" (ie transformation to the final HTML) using the ReactDOM's renderToString method and simply sending that output to the response (res.send(...)) instead of attempting to render it (res.render(...)). ...这里的关键是使用ReactDOM的renderToString方法执行“渲染”(即,转换为最终的HTML),然后简单地将该输出发送到响应(res.send(...)),而不是尝试呈现它(res.render(...))。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM