gpt4 book ai didi

reactjs - enzyme :用浅层,redux store更新不会触发componentDidUpdate

转载 作者:行者123 更新时间:2023-12-03 14:18:16 24 4
gpt4 key购买 nike

我在测试 React 组件的一个非常具体的用例时遇到问题。在本例中,我有一个组件在挂载时分派(dispatch)一个操作,然后在第一次分派(dispatch)的结果传入后分派(dispatch)另一个操作。

我认为,问题归结为 enzyme 的 shallow 方法没有在我的组件中调用 componentDidUpdate 。我已经用最简单的代码重现了该问题,并确认如果我使用 mount 而不是 shallow,问题就会消失。然而,enzyme's documentation据说从版本 3 开始,shallow 确实会调用 React 的生命周期方法,例如 componentDidUpdate。当然,我不能在测试中使用 mount ,因为我不想挂载整个树(在我的例子中,这意味着加载整个应用程序)。

因此我想知道:这是 enzyme 中的错误,还是我在使用该库时遗漏了某些内容?

这是我的代码示例:

import * as React from 'react';
import { connect } from 'react-redux';
import { createStore } from 'redux';

import { shallow } from 'enzyme';
import sinon from 'sinon';


const actions = {
// This would fetch a resource on the network.
getList: () => {},

receiveList: list => {
return {
type: 'RECEIVE_LIST',
list,
};
},

// This would fetch a list of resources on the network.
getObjects: () => {},
};


const reducer = (state = { list: [] }, action) => {
switch (action.type) {
case 'RECEIVE_LIST':
return { ...state, list: action.list };
default:
return state;
}
};


class MyAppBase extends React.Component {
componentDidMount() {
this.props.dispatch(actions.getList());
}

componentDidUpdate(nextProps) {
if (nextProps.list !== this.props.list) {
this.props.dispatch(actions.getObjects(nextProps.list));
}
}

render() {
return null;
}
}


const MyApp = connect(state => { return { list: state.list }; })(MyAppBase);



describe('<MyApp>', () => {
it('fetches objects once list is received', () => {
// Mock actions that call the network.
sinon.stub(actions, 'getList');
actions.getList.returns({type: 'whatever'});
sinon.stub(actions, 'getObjects');
actions.getObjects.returns({type: 'whatever'});

// Create a redux store.
const store = createStore(reducer);

// Create the component.
const wrapper = shallow(<MyApp store={store} />);

// Verify that `componentDidMount` was called but not `componentDidUpdate`.
expect(actions.getList.callCount).toEqual(1);
expect(actions.getObjects.callCount).toEqual(0);

// Dispatch an action that will change the redux store.
store.dispatch(actions.receiveList([ 'aa', 'bb' ]));

// Expect the `componentDidUpdate` method to be called.
expect(actions.getObjects.callCount).toEqual(1);

// This doesn't work, for some reason `componentDidUpdate` is never called.
});
});

我为此使用的软件包版本:

"react": "16.6.0",
"react-dom": "16.6.0",
"react-redux": "5.1.0",
"redux": "4.0.1",
"enzyme": "3.7.0",
"enzyme-adapter-react-16": "1.6.0",
"sinon": "7.1.0"

谢谢!

最佳答案

Enzyme 的“shallow”方法似乎并不完全支持“componentDidUpdate”方法。

安装的组件似乎仅在调用wrapper.setProps()之后调用componentDidUpdate。存储更新为新状态并不重要,包装器只是没有更新。

这可以通过更改测试来执行以下操作来确认:

// Dispatch an action that will change the redux store.
store.dispatch(actions.receiveList([ 'aa', 'bb' ]));

// Will print '[]'
console.log(wrapper.instance().props.list);

// Create a new wrapper with the current store:
const wrapper2 = shallow(<MyApp store={store} />);

// Will print '['aa', 'bb']'
console.log(wrapper2.instance().props.list)

解决方法是在 store.dispatch 之后调用 setProps (或者最好只使用 mount 而不是 shallow,如果可行的话):

// Dispatch an action that will change the redux store.
store.dispatch(actions.receiveList([ 'aa', 'bb' ]));

// Manually cause componentDidUpdate to trigger
wrapper.setProps({
list: ['aa', 'bb']
});

此外,componentDidUpdate 可以由 simulate 方法触发,用于单击或更改按钮或输入。

关于reactjs - enzyme :用浅层,redux store更新不会触发componentDidUpdate,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53283896/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com