如何访问由 HOC 包装的嵌套 React 组件上的状态? [英] How does one access state on a nested React component wrapped by an HOC?

查看:21
本文介绍了如何访问由 HOC 包装的嵌套 React 组件上的状态?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 Enzyme,我们实际上可以使用 example 文档中给出的组件作为我问题的基础.

让我们假设这个 <Foo/> 组件使用来自 ReactRouter 的 <Link> 组件,因此我们需要将它包装在一个 <MemoryRouter> 用于测试.

问题就在这里.

it('把乳液放在篮子里', () => {const 包装器 = 安装(<MemoryRouter><Foo/></MemoryRouter>)wrapper.state('name')//这将返回 null!我们正在访问 MemoryRouter 的状态,这不是我们想要的!wrapper.find(Foo).state('name')//这中断了!state() 只能在根上调用!})

所以,不确定在使用 时如何访问本地组件状态.

也许我在做一个无知的测试?是否试图在测试中获取/设置组件状态不好的做法?我无法想象,因为 Enzyme 有获取/设置组件状态的方法.

只是不确定应该如何访问包裹在 中的组件的内部结构.

任何帮助将不胜感激!

解决方案

最新版本 Enzyme 有一个潜在的解决方案,可以解决访问子组件状态的问题.

假设我们有 (注意使用 React Router 的 )

class Foo extends Component {状态 = {酒吧:'这里是状态!}使成为 () {返回 (<Link to='/'>这是一个链接</Link>)}}

<块引用>

注意:以下代码仅在 Enzyme v3 中可用.

重新审视测试代码,我们现在可以编写以下内容

it('把乳液放在篮子里', () => {const 包装器 = 安装(<MemoryRouter><Foo/></MemoryRouter>)期望(wrapper.find(Foo).instance().state).toEqual({酒吧:'这里是状态!})})

使用 wrapper.find(Child).instance() 我们可以访问 Child 的状态,即使它是一个嵌套组件.在之前的 Enzyme 版本中,我们只能访问根目录上的 instance.您还可以在 Child 包装器上调用 setState 函数!

我们可以在浅渲染测试中使用类似的模式

it('把洗液放在篮子里浅',() => {const 包装器 = 浅(<MemoryRouter><Foo/></MemoryRouter>)期望(wrapper.find(Foo).dive().instance().state).toEqual({酒吧:'这里是状态!})})

注意dive的使用在浅层测试中,可以在单个非 DOM 节点上运行,并将返回浅渲染的节点.

<小时>

参考:

I'm using Enzyme, and we can actually use the example component given in the docs as a foundation for my question.

Let's assume this <Foo /> component uses a <Link> component from ReactRouter and thus we need to wrap it in a <MemoryRouter> for testing.

Herein lies the problem.

it('puts the lotion in the basket', () => {
  const wrapper = mount(
    <MemoryRouter>
      <Foo />
    </MemoryRouter>
  )

  wrapper.state('name') // this returns null! We are accessing the MemoryRouter's state, which isn't what we want!
  wrapper.find(Foo).state('name') // this breaks! state() can only be called on the root!
})

So, not exactly sure how to access local component state when using <MemoryRouter>.

Perhaps I'm performing an ignorant test? Is trying to get/set component state bad practice in testing? I can't imagine it is, as Enzyme has methods for getting/setting component state.

Just not sure how one is supposed to access the internals of a component wrapped in <MemoryRouter>.

Any help would be greatly appreciated!

解决方案

So it seems with the latest release of Enzyme there is a potential fix for this issue of accessing state on a child component.

Let's say we have <Foo> (note the use of React Router's <Link>)

class Foo extends Component {
  state = {
    bar: 'here is the state!'
  }

  render () {
    return (
      <Link to='/'>Here is a link</Link>
    )
  }
}

Note: The following code is only available in Enzyme v3.

Revisiting the test code, we are now able to write the following

it('puts the lotion in the basket', () => {
  const wrapper = mount(
    <MemoryRouter>
      <Foo />
    </MemoryRouter>
  )

  expect(wrapper.find(Foo).instance().state).toEqual({
    bar: 'here is the state!'
  })
})

Using wrapper.find(Child).instance() we are able to access Child's state even though it is a nested component. In previous Enzyme versions we could only access instance on the root. You can also call the setState function on the Child wrapper as well!

We can use a similar pattern with our shallowly rendered tests

it('puts the lotion in the basket shallowly', () => {
  const wrapper = shallow(
    <MemoryRouter>
      <Foo />
    </MemoryRouter>
  )

  expect(wrapper.find(Foo).dive().instance().state).toEqual({
    bar: 'here is the state!'
  })
})

Note the use of dive in the shallow test, which can be run on a single, non-DOM node, and will return the node, shallow-rendered.


Refs:

这篇关于如何访问由 HOC 包装的嵌套 React 组件上的状态?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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