如何在HOC包装的嵌套React组件上访问状态?

时间:2017-07-07 21:14:25

标签: react-router jestjs enzyme react-router-v4

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

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

这就是问题所在。

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!
})

因此,在使用<MemoryRouter>时,不确定如何访问本地组件状态。

也许我正在进行无知的测试?试图在测试中获取/设置组件状态不良做法?我无法想象,因为Enzyme有获取/设置组件状态的方法。

不确定如何访问<MemoryRouter>中包含的组件的内部。

非常感谢任何帮助!

2 个答案:

答案 0 :(得分:17)

因此,似乎在酶的latest release中,可以解决在子组件上访问状态的问题。

我们说<Foo>(注意使用React Router&#39; s <Link>

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

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

注意:以下代码仅适用于Enzyme v3。

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

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!'
  })
})

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

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

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!'
  })
})

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

参考:

答案 1 :(得分:0)

认为对您可能有用,因为我偶然发现了这一点并进行了修复。

就我而言,我有一个连接到redux的组件。

---Design.vhd---

library IEEE;
use IEEE.std_logic_1164.all;

entity Design is
port(
      I_CLK: in std_logic;
      I_RESET: in std_logic;
      O_PLLOUTGLOBAL : out std_logic
    );
end entity Design;

architecture RTL of Design is

begin

SO_pll_inst: entity SO_pll
port map(
          REFERENCECLK => I_CLK,
          PLLOUTCORE => open,
          PLLOUTGLOBAL => O_PLLOUTGLOBAL,
          RESET => I_RESET
        );

end RTL;

connect()显然是HOC组件。 那么我们如何在这里访问“ ComponentName”?

非常简单:

class ComponentName extends Component {
...
}
export default connect(
  mapStateToProps,
  {
...
 }
)(ComponentName );