Tengo lo que pensé que sería una prueba simple para probar los cambios de estado, tengo otra prueba que hace el cambio por temporizador y funcionó correctamente (al menos supongo que sí), pero esta se activa con un evento de click y está fallando mi volver a hacer el cheque.
it("should not rerender when setting state to the same value via click", async () => { const callback = jest.fn(); function MyComponent() { const [foo, setFoo] = useState("bir"); callback(); return (<div data-testid="test" onClick={() => setFoo("bar")}>{foo}</div>); } const { getByTestId } = render(<MyComponent />) const testElement = getByTestId("test"); expect(testElement.textContent).toEqual("bir"); expect(callback).toBeCalledTimes(1); act(() => { fireEvent.click(testElement); }); expect(testElement.textContent).toEqual("bar"); expect(callback).toBeCalledTimes(2); act(() => { fireEvent.click(testElement); }); expect(testElement.textContent).toEqual("bar"); expect(callback).toBeCalledTimes(2); // gets 3 here })Traté de hacer lo mismo usando codesandbox https://codesandbox.io/s/rerender-on-first-two-clicks-700c0
Lo que descubrí al mirar los registros es que se vuelve a renderizar en los primeros dos clics, pero mi expectativa era que se volviera a renderizar en el primer clic, ya que el valor es el mismo.
También hice algo similar en React native a través de un snack y funciona correctamente. Solo una re-renderización. Entonces puede ser algo específicamente en onClick en React-DOM #22940
Implemente shouldComponentUpdate para renderizar solo cuando cambien el estado o las propiedades.
Aquí hay un ejemplo que usa shouldComponentUpdate , que funciona
solo para este caso de uso simple y fines de demostración. Cuando esto
se utiliza, el componente ya no se vuelve a representar con cada clic y se representa cuando se muestra por primera vez y después de que se haya hecho clic en él una vez.
var TimeInChild = React.createClass({ render: function() { var t = new Date().getTime(); return ( <p>Time in child:{t}</p> ); } }); var Main = React.createClass({ onTest: function() { this.setState({'test':'me'}); }, shouldComponentUpdate: function(nextProps, nextState) { if (this.state == null) return true; if (this.state.test == nextState.test) return false; return true; }, render: function() { var currentTime = new Date().getTime(); return ( <div onClick={this.onTest}> <p>Time in main:{currentTime}</p> <p>Click me to update time</p> <TimeInChild/> </div> ); } }); ReactDOM.render(<Main/>, document.body); <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.0/react.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.0/react-dom.min.js"></script>