如何访问由 HOC 包装的嵌套 React 组件的状态?
How does one access state on a nested React component wrapped by an HOC?
我正在使用文档中提供的 Enzyme, and we can actually use the 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>
时如何访问本地组件状态。
也许我在进行无知的测试?试图 get/set 组件状态测试中的不良做法?我无法想象它是,因为 Enzyme 有 getting/setting 组件状态的方法。
只是不确定应该如何访问包裹在 <MemoryRouter>
.
中的组件的内部结构
如有任何帮助,我们将不胜感激!
因此,Enzyme 的 latest release 似乎可以解决访问子组件状态的问题。
假设我们有 <Foo>
(注意使用 React Router 的 <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.
重新访问测试代码,我们现在可以编写以下内容
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
。您也可以在 Child
包装器上调用 setState
函数!
我们可以在浅层渲染测试中使用类似的模式
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节点上运行,并将return节点,浅渲染。
参考:
认为它可能对你们有用,因为我偶然发现了这个问题并进行了修复。
在我的例子中,我有一个连接到 redux 的组件。
class ComponentName extends Component {
...
}
export default connect(
mapStateToProps,
{
...
}
)(ComponentName );
connect() 显然是一个 HOC 组件。
那么我们如何访问这里的 "ComponentName" 呢?
很简单:
component
.find(ComponentName)
.children()
.first()
.props() // returns ComponentName's props
我正在使用文档中提供的 Enzyme, and we can actually use the 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>
时如何访问本地组件状态。
也许我在进行无知的测试?试图 get/set 组件状态测试中的不良做法?我无法想象它是,因为 Enzyme 有 getting/setting 组件状态的方法。
只是不确定应该如何访问包裹在 <MemoryRouter>
.
如有任何帮助,我们将不胜感激!
因此,Enzyme 的 latest release 似乎可以解决访问子组件状态的问题。
假设我们有 <Foo>
(注意使用 React Router 的 <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.
重新访问测试代码,我们现在可以编写以下内容
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
。您也可以在 Child
包装器上调用 setState
函数!
我们可以在浅层渲染测试中使用类似的模式
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节点上运行,并将return节点,浅渲染。
参考:
认为它可能对你们有用,因为我偶然发现了这个问题并进行了修复。
在我的例子中,我有一个连接到 redux 的组件。
class ComponentName extends Component {
...
}
export default connect(
mapStateToProps,
{
...
}
)(ComponentName );
connect() 显然是一个 HOC 组件。 那么我们如何访问这里的 "ComponentName" 呢?
很简单:
component
.find(ComponentName)
.children()
.first()
.props() // returns ComponentName's props