Home > Mobile >  Why the button event doesnt increment the counter?
Why the button event doesnt increment the counter?

Time:04-19

I tried to increment the counter in the test but when i press the button the value doesnt change. I used the fireEvent from React testing library and React test utils but the value still in 10.I use react 18.
CounterApp:

import {useState} from "react";
import PropTypes from "prop-types";
const CounterApp = ({value=10})=>{
const [counter,setCounter] = useState(value);
const handleAdd= ()=>{
        setCounter(counter 1);
    }
    const handleSubstract = ()=>{
        if(counter>0){
            setCounter(counter-1);
        }
       
    }
    const handleReset = ()=>{
        setCounter(0);
    }
    return(
        <>
            <h1>CounterApp</h1>
            <h2>{counter}</h2>
            <button onClick={handleAdd}> 1</button>
            <button onClick={handleSubstract}>-1</button>
            <button onClick={handleReset}>Reset</button>

        </>
    );
}
CounterApp.propTypes={
    value: PropTypes.number.isRequired
}
export default CounterApp;

And the test archive:

import { create} from "react-test-renderer";
import CounterApp from "../CounterApp";
import '@testing-library/jest-dom';
import ReactTestUtils from 'react-dom/test-utils'; 
import {fireEvent} from "@testing-library/react";
describe("Test in counterApp",()=>{
  test("Should be increment the count",()=>{
        const component = create(<CounterApp value={10}/>);
        const values= component.root;
        const button=values.findAllByType("button").at(0).props;
        const counter = values.findByType("h2").props.children;
        ReactTestUtils.Simulate.click(button);
         expect(counter).toBe("11");
    })
})

CodePudding user response:

You should format your component. Otherwise it's hard to read and you'll get issues because of that.

I couldn't understand if it works fine on a manual test, so not sure if the issue is on the testing or the component itself.

When using the setter in useState you have a callback, so instead of using the getter, you should do:

const handleAdd = () => {
    setCounter(prev => prev   1);
}

For the testing you should use an id to better identify the button, not the type.

CodePudding user response:

You made a mistake to update state variable using the previous state value.

ReactJS setState()

All the React components can have a state associated with them. The state of a component can change either due to a response to an action performed by the user or an event triggered by the system. Whenever the state changes, React re-renders the component to the browser. Before updating the value of the state, we need to build an initial state setup. Once we are done with it, we use the setState() method to change the state object. It ensures that the component has been updated and calls for re-rendering of the component.

setState({ stateName : updatedStateValue })

// OR
setState((prevState) => ({ 
   stateName: prevState.stateName   1 
}))

So you should use like the following.

    const handleAdd= ()=>{
        setCounter(prev => prev 1);
    }
    const handleSubstract = ()=>{
        if(counter>0){
            setCounter(prev => prev-1);
        }
       
    }
  • Related