首页 > 解决方案 > ReactJs 点击后状态不更新

问题描述

我使用 Enzyme 和 Jest 测试我的 React 应用程序。这是我的组件:

function App() {
    const [state, setState] = React.useState('default');
    const [loading, setLoading] = React.useState(false);
    const [name, setName] = React.useState('ji');
    return (
        <div className="App">
            <h2>{state}</h2>
            <h1 className='test'>Helljo</h1>
            <h1 className='test'>Hello</h1>
            <button onClick={() => {
                setState('changed');
                setLoading(true)
            }}>Click</button>
            <Child setName={setName} name={name}/>
        </div>
    );
}

export default App;

单击按钮我更新h2标签中的文本。
下面是我的测试,应该测试这个事件:

import { configure,  shallow, mount, render } from 'enzyme';
import App from './App';
import React, {useState} from "react";


describe('Test main component', () => {
  let wrapper = shallow(<App />);
  let setState;
  let setName;
  let setLoading;

  beforeEach(() => {

    setState = jest.fn(x => {});
    setName = jest.fn(x => {});
    setLoading = jest.fn(x => {});

    React.useState = jest.fn()
        .mockImplementationOnce(state => [state, setState])
        .mockImplementationOnce(loading => [loading, setLoading])
        .mockImplementationOnce(name => [name, setName])
  });
  
  afterEach(() => {
    jest.clearAllMocks();
  });
  
  test('should change state on text', () => {
    const btn = wrapper.find("button");
    btn.simulate("click");
    expect(wrapper.find('h2').text()).toBe('changed');
  })
})

运行这个测试我得到:

Expected: "changed"
Received: "default"

为什么我会得到这个以及如何使测试可行?注意:如果我删除该beforeEach语句,代码将按预期工作,但我需要保留该逻辑,因为我需要测试组件的状态。

问题:为什么我的代码没有检索到预期的结果以及如何解决?

标签: javascriptreactjsenzyme

解决方案


因为你模拟setState一个函数不做任何事情所以state不会更新。

setState = jest.fn(x => {});

你不能嘲笑setState。因为它涉及到更改state和重新渲染component. 所以你应该保留setState, 专注于另一个逻辑。


推荐阅读