在服务端传递属性未能在客户端渲染

3
以下的node.js代码正在使用prop渲染我的App组件...
var reactHtml = reactDom.renderToString(App({exists: true}));
res.render('../../tutorHub/views/index.jade', {reactOutput: reactHtml});

这个组件可以在我的jade文件中被引用,如下所示...

#app != reactOutput

现在在组件内部,我正在检查是否已经渲染了该属性...
render(){

        console.log(this.props.exists);
...
...

当我在终端上运行此代码时,控制台会输出true。然而,在我的浏览器终端中,我得到了undefined,这意味着在设置属性后,React在客户端上重新渲染了组件。
我正在拼命寻找解决方法,我不想重构整个网站。有人能帮我解决这个问题吗?
我需要如何防止重新渲染?
编辑:
所以在我的node.js文件中,我做了以下操作...
var reactHtml = reactDom.renderToString(App({}));
res.render('../../tutorHub/views/index.jade', {reactOutput: reactHtml, errorExist:true});

在我的jade文件中,我做了以下操作...
#app != reactOutput

script(type='text/javascript')                                                   
    window.data =!{JSON.stringify(errorExist)};

但是现在我尝试在我的组件中检索数据...

if (window.data) {
        return (
            <Register />

            );
        }
        else {
            return (
            <Index event={this.handleClick.bind(this)} />

            );
        }  

但是我会收到错误提示:windowdata 未定义


你是否已经仔细检查客户端在渲染时是否也传递了相同的属性集?前端重新渲染实际上是非常正常的。你需要的是客户端和服务器之间数据的近乎完美的一对一映射关系。一个技巧是直接将数据与 HTML 嵌入,可以放在脚本标签中,以 JSON 编码的形式展示。 - Sal Rahman
@SalehenRahman 我明白了,你所说的直接嵌入数据是什么意思?你有例子或者其他东西吗? - buydadip
在Jade代码中,它看起来会像这样:script = JSON.stringify(myData) - Sal Rahman
然后,在客户端渲染应用程序之前,您将从脚本标记中获取数据,并在渲染时将它们作为属性传递。 - Sal Rahman
@SalehenRahman 好的,我尝试了你的方法,但是有一部分卡住了,你能看一下我的修改吗?谢谢。 - buydadip
在你的编辑中,data 是在 React 渲染之前还是之后定义的?另外,你可以尝试的另一件事情是,不要将 data 声明为一个变量,而是将 data 属性分配到全局的 window 变量上,这样 data 就几乎可以在任何地方使用了。 - Sal Rahman
1个回答

2

我们将{exists: true}称为初始状态。

1. 在服务器上:使用JSON.stringify序列化初始状态,并将其存储在jade模板中。

node.js

var reactHtml = reactDom.renderToString(App({exists: true}));
res.render('../../tutorHub/views/index.jade', {
  reactOutput: reactHtml, 
  initialState: JSON.stringify({exists: true})
});

Jade 文件

#app != reactOutput

#initialState =! initialState

2. 在客户端: 从DOM获取初始状态,并在App react组件的getInitialState生命周期方法中使用JSON.parse进行反序列化。

App react组件

getInitialState() {
  return JSON.parse(document.getElementById('initialState').innerHTML)
}
  1. exists 布尔值现在可以通过 this.state.existsApp 组件的状态中访问。

我尝试了你的方法,但是我遇到了“document is not defined”错误,这是为什么? - buydadip
请在“getInitialState”中添加检查以检测是否可用“document”。 它不会在服务器上渲染。例如 if(typeof document ==='undefined')return {}; - Michal K.
据我所知,在服务器端渲染中,浏览器窗口尚未创建,因此document对象和window对象都不可用。 - xploreraj

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接