ReactJS:为什么将组件的初始状态传递给prop是反模式?

reactjs React.js

Green老丝Itachi

2020-03-13

我已经在SocketIO的帮助下创建了一个小的ReactJS仪表板,用于实时更新。即使我更新了仪表板,也使我感到不确定我是否正确执行了操作。

最让我感到困扰的是getInitialState中Props作为反模式发布。我创建了一个仪表板,该仪表板从服务器获取实时更新,除了加载页面外,不需要用户交互。根据我的阅读,this.state应该包含一些内容,这些内容将确定是否应重新渲染该组件,以及this.props....我还不知道。

但是,最初调用时React.render(<MyComponent />, ...),只能传递道具。就我而言,我从服务器获取了所有数据,因此this.state无论如何,最初的道具最终还是会结束所以我所有的组件都有这样的东西:

getInitialState: function() {
    return {
        progress: this.props.progress,
        latest_update: this.props.latest_update,
        nearest_center: this.props.nearest_center
    }
}

除非我对上述博客文章有误解,否则这是反模式。但是我看不到将状态注入Component的其他方法,而且我不明白为什么它是一种反模式,除非我重新标记所有道具以使其成为前提initial如果有的话,我觉得那是一种反模式,因为现在我必须跟踪比以前更多的变量(那些有initial没有的变量)。

第1461篇《ReactJS:为什么将组件的初始状态传递给prop是反模式?》来自Winter(https://github.com/aiyld/aiyld.github.io)的站点

1个回答
凯JinJin 2020.03.13

免责声明:当我回答这个问题时,我正在学习/尝试实现Vanilla Flux,对此我有些怀疑。后来我将所有内容迁移到Redux。因此,建议:只需使用Redux或MobX。您甚至可能不再需要该问题的答案(科学除外)。

将初始状态作为a传递给组件prop是一种反模式,因为该getInitialState方法仅在组件首次呈现时才调用。这意味着,如果您重新渲染该组件并传递一个不同的值a prop,则该组件将不会做出相应的反应,因为该组件将从首次渲染起就保持该状态。这很容易出错。

这是您应该做的:

尝试使您的组件尽可能无状态。无状态组件更易于测试,因为它们基于输入呈现输出这样简单。

但是,嘿..我的组件数据发生了变化..我无法使它们成为无状态

是的,您可以,对于大多数人来说。为此,请选择一个外部组件作为状态持有者。使用您的示例,您可以创建一个Dashboard包含数据的Widget组件,以及一个完全无状态组件。Dashboard负责获取所有数据,然后呈现多个Widgets接收他们需要通过一切props

但是我的窗口小部件具有某种状态。用户可以对其进行配置。我如何使它们无状态?

Widget可以公开事件,这些事件在处理后会导致其中包含的状态Dashboard发生更改,从而导致每个事件都被Widget重新呈现。您可以Widget通过props接收事件来创建“事件”

好的,所以现在,仪表板保留状态,但是如何将初始状态传递给它?

您有两个选择。最推荐的Dashboard getInitialState方法是,您在方法中进行Ajax调用以从服务器获取初始状态。您还可以使用Flux,这是一种用于管理数据的更复杂的方法。助焊剂更多是一种模式,而不是一种实现。您可以在Facebook的实现中使用纯Flux Dispatcher,但是可以使用ReduxAltFluxxor等第三方实现

另外,您可以将此初始状态作为传递prop给,例如Dashboard,明确声明这只是初始状态initialData但是,如果选择此路径,则无法向后传递不同的初始状态,因为它会“记住”第一次渲染后的状态。

OBS

您的定义不太正确。

状态用于存储可变数据,即在组件生命周期中将要更改的数据。状态更改应通过setState方法进行,并将导致组件重新呈现。

道具用于将不可更改的数据传递到组件。它们在组件生命周期中不应更改。仅使用道具的组件是无状态的。

This is a relevant source on the "how to pass the initial state to components".

问题类别

JavaScript Ckeditor Python Webpack TypeScript Vue.js React.js ExpressJS KoaJS CSS Node.js HTML Django 单元测试 PHP Asp.net jQuery Bootstrap IOS Android