ReactJS:为什么将组件初始状态传递给 prop 是一种反模式? [英] ReactJS: Why is passing the component initial state a prop an anti-pattern?

查看:25
本文介绍了ReactJS:为什么将组件初始状态传递给 prop 是一种反模式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I've created a small ReactJS dashboard with the help of SocketIO for live updates. Even though I have the dashboard updating, it bugs me that I'm not quite sure if I did it correctly.

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

What bugs me the most is the Props in getInitialState as anti-pattern post. I've created a dashboard that gets live updates from a server, requiring no user interaction beyond loading the page. From what I've read, this.state should contain things that will determine whether the component should be re-rendered, and this.props.... I don't know yet.

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

However, when you initially call React.render(<MyComponent />, ...), you can only pass props. In my case, I get all data from the server, so the initial props just end up in this.state anyway. So all of my components have something like this:

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

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

Which, unless I've misinterpreted the aforementioned blog post, is an anti-pattern. But I see no other way of injecting the state into the Component, and I don't understand why it's an anti-pattern unless I relabel all of my props to prepend initial on them. If anything, I feel like that's an anti-pattern because now I have to keep track of more variables than I did before (those prepended with initial and those without).

推荐答案

免责声明:当我回答这个问题时,我正在学习/试图实现 vanilla Flux,我对此有点怀疑.后来我将所有内容迁移到 Redux.所以,一个建议:使用 Redux 或暴徒X.有可能你甚至不需要这个问题的答案不再(科学除外).

Disclaimer: When I answered this question I was learning / trying to implement vanilla Flux and I was a bit skeptic about it. Later on I migrated everything to Redux. So, an advice: Just go with Redux or MobX. Chances are you won't even need the answer to this question anymore (except for the science).

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

Passing the intial state to a component as a prop is an anti-pattern because the getInitialState method is only called the first time the component renders. Meaning that, if you re-render that component passing a different value as a prop, the component will not react accordingly, because the component will keep the state from the first time it was rendered. It's very error prone.

这是你应该做的:

尽量让你的组件无状态.无状态组件更容易测试,因为它们基于输入呈现输出.就这么简单.

Try to make your components as stateless as possible. Stateless components are easier to test because they render an output based on an input. Simple like that.

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

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

Yes you can, for most of them. In order to do that, select an outer component to be the state holder. Using your example, you could create a Dashboard component that contains the data, and a Widget component that is completely stateless. The Dashboard is responsible for getting all the data and then rendering multiple Widgets that receive everything they need through props.

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

您的 Widget 可以公开事件,这些事件在处理时会导致 Dashboard 中包含的状态发生变化,从而导致每个 Widget 重新呈现.通过让 props 接收函数,您可以在 Widget 中创建事件".

Your Widget can expose events that, when handled, cause the state contained in Dashboard to change, causing every Widget to be rerendered. You create "events" in your Widget by having props that receive a function.

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

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

You have two options. The most recomended one, is that you make an Ajax call in the Dashboard getInitialState method to get the initial state from the server. You can also use Flux, which is a more sophisticated way for managing data. Flux is more of a pattern, rather than an implementation. You can use pure Flux with the Facebook's implementation of the Dispatcher, but you can use third-party implementations like Redux, Alt or Fluxxor.

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

Alternatively, you can pass this initial state as a prop to the Dashboard, explicitly declaring that this is just the initial state.. like initialData, for instance. If you choose this path, though, you can't pass a different initial state to it aftwards, because it will "remember" the state after the first render.

OBS

你的定义不太正确.

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

State is used to store mutable data, that is, data that is going to change during the component life-cycle. Changes in the state should be made through the setState method and will cause the component to re-render.

Props 用于向组件传递不可变数据.它们不应在组件生命周期中更改.只使用 props 的组件是无状态的.

Props are used to pass in imutable data to the components. They should not change during the component life-cycle. Components that only use props are stateless.

这是一个如何将初始状态传递给组件"的相关来源.

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

这篇关于ReactJS:为什么将组件初始状态传递给 prop 是一种反模式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆