Reactjs redux连接的组件无法使用redux RApper.setState
请先阅读,然后再将其标记为副本 所以,我检查了所有建议的问题,并进行了近2天的研究,以找出问题背后的原因 这是我所拥有的- 1。名为SignIn的组件,其某些本地状态连接到redux存储Reactjs redux连接的组件无法使用redux RApper.setState,reactjs,redux,react-redux,jestjs,enzyme,Reactjs,Redux,React Redux,Jestjs,Enzyme,请先阅读,然后再将其标记为副本 所以,我检查了所有建议的问题,并进行了近2天的研究,以找出问题背后的原因 这是我所拥有的- 1。名为SignIn的组件,其某些本地状态连接到redux存储 class SignIn extends React.Component { constructor(props) { super(props); this.state = { isLoading: false }; } render () { isLoading ?
class SignIn extends React.Component {
constructor(props) {
super(props);
this.state = { isLoading: false };
}
render () {
isLoading
? <SomeLoadingComponent />
: <MainSigninComponent />
}
}
export default ConnectedSignIn = connect(mapStateToProps)(SignIn);
类签名扩展了React.Component{
建造师(道具){
超级(道具);
this.state={isLoading:false};
}
渲染(){
卸载
?
:
}
}
导出默认ConnectedSignIn=connect(mapStateToProps)(SignIn);
现在您可以看到SignIn的渲染输出随着本地状态的变化而变化,我打算对这两个输出进行快照测试
所以我写了两个测试用例
// This one is alright as it test on the default state and renders the actual SigninComponent.
test(`it renders correctly`, () => {
const wrapper = shallow(<ConnectedSignIn {...props} />, { context: { store }});
// .dive() because I intend to snapshot my actual SignIn component and not the connect wrapper.
expect(wrapper.dive()).toMatchSnapshot();
});
//这一个是正常的,因为它在默认状态下进行测试并呈现实际的SigninComponent。
测试(`it正确呈现`,()=>{
const wrapper=shallow(,{context:{store}});
//.dive(),因为我打算快照我的实际登录组件,而不是连接包装器。
expect(wrapper.dive()).toMatchSnapshot();
});
现在,当我打算将状态更改为{isLoading:true}时,我会在第二个测试中这样调用setState
test(`it renders the loading view on setting isLoading state to true`, () => {
const wrapper = shallow(<ConnectedSignIn {...props} />, { context: { store }});
console.log(wrapper.dive().state()) // returns { isLoading: false }
// Again .dive because I want to call setState on my SignIn component
wrapper.dive().setState({ isLoading: true });
console.log(wrapper.dive().state()) // still returns { isLoading: false }
// Tried the callback method to ensure async op completion
wrapper.dive().setState({ isLoading: true }, () => {
console.log(wrapper.dive().state()) // still returns { isLoading: false }
});
});
test(`it在将isLoading状态设置为true时呈现加载视图`,()=>{
const wrapper=shallow(,{context:{store}});
console.log(wrapper.dive().state())//返回{isLoading:false}
//再次。潜水,因为我想在我的登录组件上调用setState
wrapper.dive().setState({isLoading:true});
console.log(wrapper.dive().state())//仍然返回{isLoading:false}
//尝试回调方法以确保异步操作完成
wrapper.dive().setState({isLoading:true},()=>{
console.log(wrapper.dive().state())//仍然返回{isLoading:false}
});
});
根据上面的代码和输出,我推断浅层包装器的setState不能正常工作,就像没有实际更新组件的状态一样
更何况,
1。我还尝试使用wrapper.dive().instance().setState()
正如我在一些问题中读到的,更新实例的状态,这种方式会更好不起作用。
2.我还尝试使用wrapper.update()和wrapper.dive().update()对变浅的组件强制更新。这个也没用
我的依赖项版本
“反应”:“16.0.0”
“反应本机”:“0.50.0”
“react redux”:“^5.0.6”
“酶”:“^3.3.0”
“酶-适配器-反应-16”:“^1.1.1”
“笑话”:“21.2.1”
“react dom”:“^16.2.0”
我已经阅读了通过将组件与redux分离来单独测试组件的指南。我这样做了,我的测试用例运行良好,但我想知道这种行为是正常的还是错误的,如果有人成功地测试了状态更改以及redux连接组件的渲染更改,请告诉我您的方法。尝试下面的代码。为我工作
const newWrapper=wrapper.dive();
console.log(newWrapper.state())//返回{isLoading:false};
newWrapper.setState({
孤岛加载:正确
});
console.log(newWrapper.state())//返回{isLoading:true}
这是一种不好的做法。您应该独立测试SignIn
和ConnectedSignIn
1。创建命名导出
// SignIn.js
export class SignIn extends React.Component {
constructor(props) {
super(props);
this.state = {
isLoading: false
};
}
render() {
const { isLoading } = this.state;
return (
(isLoading) ? <SomeLoadingComponent /> : <MainSigninComponent />
);
}
}
export default ConnectedSignIn = connect(mapStateToProps)(SignIn);
请注意,每次使用
dive()
时,我们都会导入SignIn
而不是ConnectedSignIn,它会创建一个新的包装,因此所有调用都引用一个新包装,而不是您更新的包装。相反,您可以尝试以下方法:
test(`it renders the loading view on setting isLoading state to true, () => {
const wrapper = shallow(<ConnectedSignIn {...props} />, { context: { store }});
const component = wrapper.dive()
component.setState({ isLoading: true });
console.log(component.state()) // should be {isLoading: true}
});
test(`it在将isLoading状态设置为true时呈现加载视图,()=>{
const wrapper=shallow(,{context:{store}});
const component=wrapper.dive()
setState({isLoading:true});
console.log(component.state())//应该是{isLoading:true}
});
作为参考,请注意。奇怪,甚至没有人尝试过。我再也受不了了。我已经采取了上述做法,但仍然对我问题中提到的问题的原因感到好奇。
test(`it renders the loading view on setting isLoading state to true, () => {
const wrapper = shallow(<ConnectedSignIn {...props} />, { context: { store }});
const component = wrapper.dive()
component.setState({ isLoading: true });
console.log(component.state()) // should be {isLoading: true}
});