【问题标题】:ReactJs: How to pass the initial state while rendering a component?ReactJs:如何在渲染组件时传递初始状态?
【发布时间】:2015-03-11 18:31:57
【问题描述】:

我知道我可以在渲染组件时传递props。我也知道getInitialState 方法。但问题是,getInitialState 并没有太大帮助,因为我的组件不知道它的初始状态。我愿意。所以我想在渲染时传递它。

类似这样的东西(伪代码):

React.render(<Component initialState={...} />);

我知道我可以使用 prop 作为初始状态,但这听起来像是一种反模式。

我该怎么办?

为清晰而编辑

假设我有一个CommentList 组件。当我第一次渲染它时,初始状态对应于我数据库中当前 cmets 的快照。由于用户包括 cmets,此列表将发生变化,这就是为什么它应该是 state 而不是 props。现在,为了呈现 cmets 的初始快照,我应该将它传递给 CommentsList 组件,因为它无法知道它。我的困惑是,我看到传递此信息的唯一方法是通过 props,这似乎是一种反模式。

【问题讨论】:

  • facebook.github.io/react/tips/… -- 我认为最后一节适用于此。如果这只是初始状态并且你说清楚了,那可能没问题。
  • @RandyMorris 实际上很有意义。如果我正在为第一个请求(Node.js 或 ReactJs.NET)进行服务器渲染,我肯定不想进行额外的 Ajax 调用来获取数据。这甚至对 SEO 都不友好。

标签: javascript reactjs


【解决方案1】:

免责声明:较新版本的 React 以不同的方式处理此问题。

只有永久组件才能使用getInitialState 中的道具。如果同步是您的目标,getInitialState 中的道具是一种反模式。 getInitialState 仅在首次创建组件时调用,因此它可能会引发一些错误,因为事实的来源不是唯一的。 Check this answer。

Quoting documentation:

使用从父级传递下来的道具来生成状态 getInitialState 通常会导致“真相来源”的重复,即 真实数据在哪里。只要有可能,即时计算值 以确保它们以后不会不同步并导致 维修麻烦

你仍然可以这样做:

getInitialState: function() {
   return {foo: this.props.foo}
}

因为它们将成为您应用的默认道具。但只要你使用一个 prop 来设置一个可能不会改变的值,你就可以在 render 函数中使用相同的 prop。

<span>{this.props.foo}</span>

此道具不会被修改,因此每次调用render 时使用它都没有问题。

编辑答案:

在这种情况下,您的初始状态不应该是道具,应该是填充评论列表的 ajax 调用。

【讨论】:

  • 感谢您的回复。所以,你是说我可以在 getInitialState 中使用道具,即使它是一种反模式?那么,您能告诉我如何解决我在问题编辑中提出的问题吗?
  • React 教程是这样的:facebook.github.io/react/docs/tutorial.html
  • Hum.. 所以,你可能会同意,为了防止多次 Ajax 调用(每个组件一个),我应该让最顶层的组件成为有状态的组件,而其他组件将用props 渲染,对吧?
  • 这将是(IMMO)的反应方式。
【解决方案2】:

引用the React docs:

使用从父级传递下来的道具在getInitialState 中生成状态通常会导致“真实数据源”的重复,即真实数据所在的位置。只要有可能,即时计算值,以确保它们以后不会不同步并导致维护问题

还有:

但是,如果您明确指出同步不是这里的目标,那么它不是反模式

所以如果你的 props 包含一个value 和一个initialValue,那么很明显后者是用于初始化的,不会混淆。

有关代码示例,请参阅 the React docs。

【讨论】:

  • 不错的答案,我应该更新我的以包含您的信息并更正反模式错误概念吗?
  • 当然,可以随意包含/复制/粘贴等。
【解决方案3】:

在看到其他答案并对其进行了一些研究之后,我得出了这个结论:

如果您在客户端(已编译或未编译)中呈现 React,这是默认方法,您应该尝试从组件内部进行额外的 Ajax 调用以获取初始状态。也就是说,不要使用props。它更干净,更不容易出错。

但是,如果您在服务器中进行渲染(Node.js 或 ReactJs.NET),则没有理由为每个请求进行额外的 Ajax 调用。此外,它对 SEO 不友好。您希望完整页面作为您的请求的结果(包括数据)。因此,正如@RandyMorris 指出的那样,在这种情况下,可以使用道具作为初始状态,只要它完全是初始状态。也就是说,没有同步。

【讨论】:

    【解决方案4】:

    如果您知道状态,那么我倾向于认为您正在渲染的组件并不能真正控制它。 React 的理念是任何特定的状态都只存在于一个位置。

    【讨论】:

    • 感谢您的回复。组件不应该知道状态。它应该渲染我告诉他渲染的任何东西?正确的?我用一个我想知道你会如何处理的场景更新了这个问题。
    • 创建列表的 cmets 的持有者将管理状态给我。 CommentList 将只负责呈现它们。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-05-24
    • 2016-05-26
    • 2018-08-14
    • 1970-01-01
    • 1970-01-01
    • 2020-01-06
    • 1970-01-01
    相关资源
    最近更新 更多