gpt4 book ai didi

reactjs - 如何使用 useReducer 钩子(Hook)测试组件?

转载 作者:行者123 更新时间:2023-12-03 13:42:35 24 4
gpt4 key购买 nike

reducer

// src/reducers/FooReducer.js

export function FooReducer(state, action) {
switch (action.type) {
case 'update': {
return action.newState;
}
// ... other actions
default:
throw new Error('Unknown action type');
}
}

组件

// src/components/BarComponent.js

export function BarComponent() {
const [state, dispatch] = useReducer(FooReducer, []);

return (
{state.map((item) => (<div />))}
);
}

测试

// src/components/BarComponent.test.js

it('should render as many divs as there are items', () => {
act(() => {
const { result } = renderHook(() => useReducer(FooReducer, [1]));
const [, dispatch] = result.current;
wrapper = mount(<BarComponent />);
dispatch({type: 'update', newState: [1, 2, 3]});
});

expect(wrapper.find(div)).toHaveLength(3);
});

上面的测试示例不起作用,但可以演示我想要实现的目标。实际上会渲染 0 个 div,因为组件中声明的初始状态包含 0 个项目。

  1. 出于测试目的,我将如何修改 reducer 的状态或更改其部署的初始状态?

  2. 我习惯了在多个组件中使用 Redux reducer ,但是 useReducer 需要传递一个初始状态...这提出了一个问题:react-hook 的 reducer 是否可以通过多个组件作为单个实例使用,还是永远都是这样2 个单独的实例?

最佳答案

在您的示例中,您尝试同时测试两件事,最好将其作为单独的测试: reducer 的单元测试,以及组件使用 reducer 的组件测试。

  1. How would I go about modifying a reducer's state or changing the initialState it is deployed with for testing purposes?

与 Redux reducer 类似,您的 reducer 可以轻松进行单元测试,因为您将其导出为纯函数。只需将您的初始状态传递到 state 参数中,并将您的操作传递到 action 中:

it('returns new state for "update" type', () => {
const initialState = [1];
const updateAction = {type: 'update', newState: [1, 2, 3] };
const updatedState = fooReducer(initialState, udpateAction);
expect(updatedState).toEqual([1, 2, 3]);
});

如果您愿意,您还可以在 useReducer 上下文中测试它:

it('should render as many divs as there are items', () => {
act(() => {
const { result } = renderHook(() => useReducer(FooReducer, [1]));
const [state, dispatch] = result.current;
dispatch({type: 'update', newState: [1, 2, 3]});
});

expect(state).toEqual([1, 2, 3]);
// or expect(state).toHaveLenth(3) if you prefer
});
  1. I am used to Redux reducers being used throughout multiple components, but useReducer needs a passed initialState... which raises the question: Is react-hook's reducer usable through multiple components asa single instance or will it always be 2 separate instances?

以下是 useReducer 与 Redux 的不同之处:您可以重用 reducer 本身,但如果您有多个 useReducer,则 state 和每个返回的 dispatch 以及初始状态都将是单独的实例。

为了测试您的 BarComponent 在 reducer 更新时更新,您需要一种从组件内触发 dispatch 的方法,因为您正在调用 useReducer在你的组件里面。这是一个例子:

export function BarComponent() {
const [state, dispatch] = useReducer(FooReducer, []);

const handleUpdate = () => dispatch({type: 'update', newState: [1, 2, 3]})

return (
<>
{state.map((item) => (<div key={item} />))}
<button onClick={handleUpdate}>Click to update state</button>
</>
);
}
it('should render as many divs as there are items', () => {
wrapper = mount(<BarComponent />);

expect(wrapper.find('div')).toHaveLength(0);

wrapper.find('button').simulate('click');

expect(wrapper.find('div')).toHaveLength(3);
});

这可能不太现实,因为我在组件本身中对新数组进行了硬编码,但希望它能给您带来想法!

关于reactjs - 如何使用 useReducer 钩子(Hook)测试组件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59275441/

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