react 状态驱动_React状态:做最少的事情

react 状态驱动

为什么国家要解决如此棘手的问题? (Why is state such a hard problem to tackle?)

State is a very hard concept to get right, but why is it so difficult? Well, ultimately the problem boils down to the fact that state is just plain old dirty. It’s a necessary evil in software development, and even the cleanest, most perfect stateless code has to hook into this horrible monster at some point. If this is inevitable, how can this pain be avoided?

状态是很难正确解决的概念,但是为什么这么难呢? 好吧,最终问题归结为以下事实:状态仅仅是普通的旧脏。 这是软件开发中必不可少的邪恶,即使是最干净,最完美的无状态代码也必须在某个时候陷入这个可怕的怪物。 如果这是不可避免的,那么如何避免这种痛苦?

Let’s start by heading into React land. The way that React encourages clean code is by limiting what code can be written. For example, in React, state is immutable. It cannot be changed on a whim via assignment; instead, it must be completely replaced though the setState() method (or through a state hook if the component is functional).

让我们开始进入React领域。 React鼓励使用干净代码的方式是限制可以编写的代码。 例如,在React中,状态是不可变的 。 不能通过分配立即更改它; 相反,必须通过setState()方法将其完全替换setState()如果组件正常运行,则通过状态挂钩)。

In addition, there is no way to directly pass data from a child to a parent component. The only way to do this is by passing a callback to the child that can then be called with the data to pass back up. This helps to reinforce the idea of unidirectional data flow, which prevents developers from doing too many messy things with state.

此外,无法将数据直接从子级传递到父级组件。 做到这一点的唯一方法是将回调传递给子级,然后该子级可以与数据一起调用以传递回去。 这有助于加强单向数据流的概念,从而防止开发人员对状态进行过多处理。

提升状态 (Lifting state)

One of the many sticky situations React developers run into is where multiple components need to be able to write to the same state. When each component has its own local state, this is impossible. How can this be resolved? By lifting the state!

React开发人员遇到的许多棘手情况之一就是多个组件需要能够写入同一状态。 当每个组件都有自己的局部状态时,这是不可能的。 如何解决? 通过解除状态

In essence, this process involves migrating the state of child components into their parent component. When a child needs to read the state, it’s passed into the child’s props. When it needs to write to the state, the parent passes it a callback that performs the operation when called.

本质上,此过程涉及将子组件的状态迁移到其父组件。 当孩子需要阅读状态时,它会传递给孩子的道具。 当需要写入状态时,父级将向其传递一个回调 ,该回调在调用时执行操作。

出现新的问题:神的零件和道具钻 (New problems arise: God components and prop drilling)

At a small scale, lifting state works very well by itself. However, once the codebase becomes big enough another unfortunate problem rears its ugly head: God components. These components grow like a cancer, absorbing state until it becomes this eldritch horror with an unholy amalgamation of 15+ separate state systems and a severe case of callback purgatory.

在小范围内,提升状态本身可以很好地发挥作用。 但是,一旦代码库变得足够大,另一个不幸的问题就会浮出水面: 上帝组件。 这些成分像癌症一样生长,吸收状态,直到通过15个以上独立的状态系统的不合逻辑的合并以及严重的回调炼狱而成为恶魔般的恐怖。

Not only are God components bad, but they introduce yet another problem: prop drilling. Since all this state now lives within a single top-level source, data must be drilled down through child props until it reaches its intended target. This clutters child components by introducing props that in no way relate to them, but can’t be removed since their children still need the data.

上帝的零件不仅不好,而且还带来了另一个问题: Struts钻Kong。 由于所有这些状态现在都存在于单个顶级来源中,因此必须通过子道具向下钻取数据,直到达到其预期目标为止。 通过引入与道具毫无关系的道具使子组件混乱,但由于子组件仍需要数据,因此无法删除它们。

使用上下文回避组件树 (Using contexts to sidestep the component tree)

For this particular set of problems, contexts are almost too perfect of a solution. Contexts live and work alongside your application, and they allow components to access data without having to drill holes deep into the app. They integrate into the app with a special provider component that allows any component underneath it to access its data.

对于这组特定的问题 上下文 几乎是完美的解决方案。 上下文与您的应用程序一起生活和工作,它们使组件可以访问数据而不必深入应用程序。 它们通过特殊的提供程序组件集成到应用程序中,该组件允许其下面的任何组件访问其数据。

On their own, contexts provide static data at a global level for components to access. However, by creating a new component that wraps the context and manages its state this static source of data can become a fully qualified state container. (Shameless plug: I wrote react-context-stateful for precisely this scenario, go check it out!)

上下文本身在全局级别上提供静态数据供组件访问。 但是,通过创建一个包装上下文并管理其状态的新组件,此静态数据源可以成为完全合格的状态容器。 (无耻的插件:我正是针对这种情况编写了react-context-stateful ,请检查一下!)

Using stateful contexts also facilitate the separation of different slices of data in the application. This way each component can grab only the contexts it needs — nothing more.

使用状态上下文还可以促进应用程序中不同数据片段的分离。 这样,每个组件只能获取其所需的上下文,仅此而已。

通过借鉴Redux的概念进一步向前迈进 (Going one step further by borrowing concepts from Redux)

Redux is a library that provides a way to create predictable state containers. This means that when a developer creates a given source of information, they also create a set of predefined actions that can be taken on that information. This is done by defining reducers, pure functions that return a new state based on the previous state and some action. This concept can be used in place of normal state to make our stateful contexts even more powerful.

Redux是一个提供创建可预测状态容器的方法的库 这意味着开发人员在创建给定的信息源时,还会创建一组可以对该信息采取的预定义操作。 这是通过定义reducers ,基于先前状态和某些操作返回新状态的纯函数来完成的。 此概念可用于代替正常状态,以使我们的有状态上下文更加强大。

使用reducers使我们的状态可测试 (Using reducers makes our state testable)

Since reducers are pure functions, testing their functionality is far easier than trying to test normal state. There’s no special inspection that has to be done to determine what the next state is going to be; rather, we can simply pass a test state and the action we want to test into our reducer and assert that the output state is what we expected!

由于reducer是纯函数 ,因此测试其功能比尝试测试正常状态要容易得多。 无需进行特殊检查即可确定下一个状态将是什么。 相反,我们可以简单地将测试状态和要测试的动作传递到reducer中,并断言输出状态就是我们所期望的!

功能组件使使用reducer作为状态更加容易 (Functional components make it easier to use reducers as state)

Because React provides the useReducer() hook for use in functional components, it’s much easier to integrate reducers into stateful contexts if you define them as functional components. Otherwise, you have to manually try to figure out how to substitute reducers for state in class components, which sounds like a pain.

因为React提供了useReducer()挂钩以用于功能组件,所以如果将reducer定义为功能组件,则将化useReducer()集成到有状态上下文中要容易得多。 否则,您必须手动尝试找出如何用还原器代替类组件中的状态,这听起来很痛苦。

我们为什么不首先使用Redux? (Why don’t we just use Redux in the first place?)

I personally avoid explicitly using Redux as a framework. It’s very boilerplate heavy, resulting in multiple files per data set, and that can stack up very quickly. Plus, in order to use the Redux store you have to wrap every component that uses it in a higher order component, which can get old real quick.

我个人避免明确使用Redux作为框架。 样板繁重,每个数据集导致多个文件,并且堆积速度非常快。 另外,为了使用Redux存储,您必须将使用它的每个组件包装在一个更高阶的组件中 ,这可以很快地变老。

不要让上下文成为您唯一的工具 (Don’t let contexts be your only tool)

As the old saying goes, “If all you have is a hammer, everything looks like a nail.” Diversify your problem-solving toolkit and choose the best tool for the job. If it makes sense to drill a piece of data down into a component, then do that. If it makes sense to create a local state for a component, then do that. If it makes sense to create a stateful context for a wide range of components, then do that. If it doesn’t make sense to use something, don’t use it.

俗话说:“如果你只有锤子,一切都将像钉子。” 多样化解决问题的工具包,并为工作选择最佳的工具。 如果有意义的是将一条数据向下钻取到一个组件中,则可以这样做。 如果有必要为组件创建局部状态,则可以这样做。 如果有必要为各种组件创建有状态上下文,则可以这样做。 如果使用某些东西没有意义, 请不要使用它。

翻译自: https://medium.com/swlh/react-state-doing-the-least-bad-thing-6f2cb20986e4

react 状态驱动

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值