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

IT技术 reactjs
2021-04-03 01:18:16

我在 SocketIO 的帮助下创建了一个小型 ReactJS 仪表板以进行实时更新。即使我更新了仪表板,我也不太确定我是否正确地进行了更新。

最让我烦恼的是getInitialState 中props作为反模式帖子。我创建了一个仪表板,可以从服务器获取实时更新,除了加载页面之外不需要用户交互。从我读过的内容来看,this.state应该包含决定组件是否应该重新渲染的内容,并且this.props......我还不知道。

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

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

除非我误解了上述博客文章,否则这是一种反模式。但是我看不出有其他方法可以将状态注入到组件中,而且我不明白为什么这是一种反模式,除非我重新标记所有props以预先添加initial它们。如果有的话,我觉得这是一种反模式,因为现在我必须跟踪比以前更多的变量(前面有initial没有的变量)。

1个回答

免责声明:当我回答这个问题时,我正在学习/尝试实现 vanilla Flux,我对此有点怀疑。后来我把所有东西都迁移到了 Redux。所以,一个建议:使用 Redux 或 MobX。很有可能你甚至不再需要这个问题的答案(科学除外)。

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

这是你应该做的:

尝试使您的组件尽可能无状态。无状态组件更容易测试,因为它们根据输入呈现输出就这么简单。

但是嘿..我的组件数据发生了变化..我不能让它们无状态

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

但是我的小部件有一些状态.. 用户可以配置它们。我如何让他们无国籍?

Widget可以公开事件,这些事件在处理时会导致其中包含的状态Dashboard发生变化,从而导致每个事件都Widget被重新渲染。您可以Widget通过props接收函数来创建“事件”

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

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

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

OBS

你的定义并不完全正确。

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

props用于在imutable数据到分量通过。它们不应在组件生命周期中更改。只使用 props 的组件是无状态的。

是“如何将初始状态传递给组件”的相关来源。

componentWillRecieveProps() 从 16.3 开始不推荐使用,所以......不。不要使用它。
2021-05-23 01:18:16
那么,对componentWillReceiveProps(nextProps)用于设置状态有什么意见吗?
2021-05-30 01:18:16
它描述得很好,但是......一如既往地是一个“但是”。如果我有一个组件,它获取图像数组并创建带有缩略图和 onlick 事件的子组件,这应该会改变这个组件中的大图像。图像未处于状态,因此我无法使用其他组件来维护它。图像是本地的,我需要一些本地状态来管理哪些应该显示为大图像。我很想在 state 中使用 props,但得到警告:setState(...):无法在现有状态转换期间更新(例如 inside render)。Render 方法应该是 props 和 state 的纯函数。
2021-06-09 01:18:16
@Alejandro -您可能不需要派生状态是对使用 (deprecated)componentWillReceiveProps或其(未弃用)替代品getDerivedStateFromProps. 底线:文章展示了几种替代解决方案,它们调用这两种方法中的任何一种,并解释了为什么要使用这些替代方法。
2021-06-14 01:18:16