当前位置: 首页 > 面试题库 >

Facebook React.js:如何在服务器上呈现状态组件?

翁翰墨
2023-03-14
问题内容

我认为我在概念上使用React.js在服务器端渲染中缺少一些东西

假设我想创建一个页面来显示服务器端数据库中的项目,并使用输入字段对其进行过滤。

我想要一个页面:

  • 响应类似的URL /items?name=foobar
  • 带有React输入字段以按名称过滤项目
  • 与React组件一起显示已过滤项目的列表

假设我有一个公共的REST API来查询客户端上的项目。

从概念上讲,我首先要执行的操作(GET /items?name=foobar)是:

  • 我希望输入字段显示用户作为参数传递的内容,因此我需要将查询参数(’foobar’)作为’prop’传递给react组件(如initialName

所以我尝试了这个:

 // A stateful component, maintaining the value of a query field
 var ItemForm = React.createClass({
    getInitialState : function () {
        return {
            name : this.props.initialName
        };
    },
    handleInputValueChanged : function() {
        var enteredName = this.refs.query.getDOMNode().value.trim();
        this.props.onNameChanged(enteredName);
    },
    render : function () {

        return React.DOM.form({
            children : [
                React.DOM.label({
                    children : "System name"
                }),
                React.DOM.input({
                    ref : "query",
                    value : this.state.name,
                    onChange : this.handleInputValueChanged
                })
            ]
        });
    }
});
  • 我还必须 在服务器上 进行数据库查询以获取项目列表,并将该项目列表作为ItemList的“ prop”传递(例如“ initialItems”)

据我了解,我需要一个简单的组件来显示列表,并将其作为“属性”接收:

 // A stateless component, displaying a list of item
 var ItemList = return React.createClass({

    propTypes : {
        items : React.PropTypes.array
    },

    render : function () {
        return React.DOM.ul({
            children : _.map(this.props.items, function (item) {
                return React.DOM.li({
                    children : [
                        React.DOM.span({
                            children : ["Name : ", item.name].join(" ")
                        })]
                });
            })
        });
    }
});
  • 现在,我需要一个组件来显示整个Page;该组件将必须维护整个页面的状态,即查看在字段中输入的名称,并进行API查询以更新列表项。但是我不明白该组件如何具有一个既可以在服务器端又可以在客户端渲染的“ initialState”。

我尝试了这个:

 // A stateful react component, maintaining the list of items
 var ItemPage = React.createClass({

    getInitialState : function () {
        // ?????
        // This is where I'm sure the problem lies. 
        // How can this be known both on server and client side ? 
        return {
            items : this.props.initialItems || []
        };
    },
    queryItems : function (enteredName) {

        var self = this;

        // The field was emptied, we must clear everything
        if (!enteredName) {
            this.setState({
                items : []
            });

        } else {

            // The field was changed, we want to do a query
            // then change the state to trigger a UI update. 
            // The query code is irrelevant, I think.
            doQuery(enteredName).then(function (items) {
                self.setState({
                   items : items
                });
            });
        }
    },
    render : function () {

        // I don't want to display the same view
        // if there is no results. 
        // This uses a 'state' property of the page
        var results = null;
        if (_.isEmpty(this.state.items)) {
            results = React.DOM.div({
                ref : "results",
                children : "No results"
            });
        } else {
            results = ItemListView({
                // Here items is a 'prop', the ItemList is technically
                // stateless
                items : this.state.items
            });
        }

        return React.DOM.div({
            children : [
                ItemForm({
                    initialName : this.props.initialName,
                    onNameChanged : this.queryItems
                }),
                results
            ]
        });
    }
});

那就是我被困住的地方。我可以使用以下方式在服务器端渲染内容:

var name = // The name from the query parameters
var items = doQueryOnServerSide(name);
React.renderComponentAsString(ItemPage({
  initialName : name,
  initialItems : items
});

但是,当我尝试编写客户端javascript时,该怎么办?我知道要在哪里渲染我的dom,但是我应该将哪些初始道具传递给react组件?

React.renderComponent(ItemPage({
  initialName : ??? // Read the name parameter from URL ? 
  initialItems : ??? // I don't know yet, and I don't want to make an API call until the user entered something in the input box 
});

我尝试过的大多数尝试最终都会在客户端上“擦除” DOM,并显示以下消息:

React尝试在容器中使用重用标记,但是校验和无效。通常,这意味着您正在使用服务器呈现,并且服务器上生成的标记不是客户端期望的。React注入了新的标记来补偿可以正常工作的标记,但是您已经失去了服务器渲染的许多好处。相反,要弄清为什么生成的标记在客户端或服务器上不同。

请注意,仅擦除了ItemList组件的标记,因此我认为这是该组件的实现问题,但我真的不知道从哪里开始。

我在正确的轨道上吗?还是我完全想念东西?


问题答案:

使用服务器渲染时,应始终传递与用于在服务器上渲染组件相同的道具。在这种情况下,您需要传递相同的initialItems道具,以获取React.renderComponent服务器渲染的标记(通过简单地对道具进行JSON化并将其放入调用中renderComponent)。

当指定时,您从initialItems读取的一般结构对我来说很有意义。这样做使您可以使用预加载的数据或不使用预加载的数据来制作组件。设置初始状态所需的条件取决于在从头开始渲染全新组件的情况下要显示的内容。(如果您始终使用服务器渲染的标记,则只需传递initialName和即可initialItems。)

希望有道理。



 类似资料:
  • 我有一个数组列表 记录在子组件中,它返回给我初始数组。 从API更改数据后 如果我在函数中将该数组记录在父组件中,我将得到一个对象数组。 它正在更改 ,但子组件没有。 我该怎么办??

  • 我知道我可以在呈现组件时传递。我还知道方法。但问题是,不太有用,因为我的组件不知道它的初始状态。我有。所以我想在渲染的时候传递它。 类似这样的内容(伪代码): 我该怎么办? 假设我有一个组件。当我第一次呈现它时,初始状态与数据库中当前注释的快照相对应。当用户包含注释时,该列表将发生更改,这就是为什么它应该是而不是。现在,为了呈现注释的初始快照,我应该将它传递给组件,因为它无法知道它。我感到困惑的是

  • 问题内容: 我试图理解这一点。通常,每次用户登录系统时,服务器端都会创建一个会话,而用户客户端端则有cookie。当人们谈论无状态服务器端,有状态客户端时,它们是什么意思?服务器端无需使用会话保持跟踪用户?只在客户端使用Cookie来检查用户?意味着如果我更换服务器,用户将不会注意到它,仍然可以继续使用该服务? 如何配置spring-security来做到这一点? 问题答案: 对于真正的无状态服务

  • 我刚开始检查react表单。我遇到了一个问题,react在渲染中标记了我试图填充输入框标签的行。以下是我的应用程序代码: 在这一点上,我所要做的就是用名称输入框的标签为“您的名字”来呈现表单,如果没有输入名称,则让react用名称输入框的标签为“您需要输入您的名字”来重新呈现表单。 非常感谢任何援助。

  • 我试图实现jwt在cookie中的auth在一个单页应用程序的反应前端,它与运行Express的各种节点微服务通信。 我这样做,因为它似乎存储的jwt在sesionstore使应用程序容易受到XSS。 然而,通过使用cookie,API现在容易受到csrf攻击。 传统上,csrf攻击是通过创建csrf令牌,将其存储在服务器会话中,然后将其呈现在隐藏的表单字段中来减轻的。然后,在提交表单时,csrf

  • 我使用kops设置了我的Kubernetes集群,并且是在本地机器上设置的。因此我的目录存储在本地计算机上,但我在中设置了状态存储。 我现在正在设置我的配置项服务器,我想从该框中运行我的命令。如何将现有状态导入该服务器?