1
  1. I have an app component and test component.
  2. I have added console.log in render method of both app as well as test component.
  3. I can see that app console is only rendered once but the test component renders twice.
  4. Also, I have a form in test component with controlled inputs but as soon as I start typing in the input fields .The test component re-renders twice .
  5. I expected it to re-render only once as state is changed once on a key press
  6. I have attached a codesandbox example for the same https://codesandbox.io/s/funny-tree-dltoc

app component

import React from "react";
import "./styles.css";
import Test from "../Test";

export default function App() {
  return (
    <div className="App">
      {console.log("rendering [APP]")}
      <Test />
      <h1>Check your console</h1>
      <h2>why test component renders twice?</h2>
      <h2> Event the test component renders twice for every key press</h2>
    </div>
  );
}

Test Component:

import React from "react";
import { useState } from "react";

const Test = () => {
  const [values, setValues] = useState({
    email: "",
    password: "",
    error: false,
    loading: false,
    didRedirect: false
  });

  const { email, password, error, loading, didRedirect } = values;
  const handleChange = name => {
    return event => {
      setValues({
        ...values,
        error: false,
        [name]: event.target.value
      });
    };
  };

  const errorMessage = (
    <div
      className="alert alert-danger"
      style={{ display: error ? "block" : "none" }}
    >
      {error}
    </div>
  );

  const onSubmit = event => {
    event.preventDefault();
    setValues({ ...values, loading: true });
  };

  const signInForm = (
    <div className="row">
      <div className="col-md-4 offset-md-4">
        <form>
          {errorMessage}
          <div className="form-group">
            <label className="text-light">Email</label>
            <input
              className="form-control"
              onChange={handleChange("email")}
              value={email}
              type="text"
            />
          </div>

          <div className="form-group">
            <label className="text-light">Passsword</label>
            <input
              className="form-control"
              type="password"
              value={password}
              onChange={handleChange("password")}
            />
          </div>
          <button className="btn btn-success btn-block" onClick={onSubmit}>
            Submit
          </button>
        </form>
      </div>
    </div>
  );

  return (
    <div>
      {console.log("rendering [test]")}
      {signInForm}
    </div>
  );
};

export default Test;



In short:

what i expected in console:
rendering [APP] 
rendering [test]

what i actually got:
rendering [APP] 
rendering [test]
rendering [test]
Abhisar Tripathi
  • 1,569
  • 10
  • 21
  • Does this answer your question? [React useState cause double rendering](https://stackoverflow.com/questions/61053432/react-usestate-cause-double-rendering) – segFault May 03 '20 at 12:17
  • the usual double rendering suspect `React.StrictMode` - https://stackoverflow.com/a/61193369/1176601 - does not seem to apply here, `App` would be rendered twice too, I guess it's due to React development mode. have you tried in production mode (`npm build`...)? – Aprillion May 03 '20 at 12:34
  • This problem seems to be appearing only when using React.StrictMode Why is that so? – Sandeep Sharma May 03 '20 at 12:58
  • @SandeepSharma Please check the duplicate post. It has the relavant information for your question – Shubham Khatri May 04 '20 at 07:24

2 Answers2

0

I think it's because codesandbox uses react devtools. I find a closed issue about it

https://github.com/facebook/react-devtools/issues/1333

Because in other environment we have only one console.log

It's demo from @ravibagul91

https://stackblitz.com/edit/react-qekebe

Oro
  • 2,250
  • 1
  • 6
  • 22
  • This problem is still there in local machine This issue seems to be because of React.StrictMode – Sandeep Sharma May 03 '20 at 12:59
  • The create-react-app now comes with following code in index.js ` ReactDOM.render( , document.getElementById('root') )` this seems to be causing re-renders – Sandeep Sharma May 03 '20 at 13:03
-1

So your test component is rendered second time because of useState hook usage. Your component need to stay up to date with state so every time it's state changes there must be rerender. You've got handleChange function which will fire each input change, this function is changing the state and the components rerenders. This is basicly how react works. Hope I helped you.

PatrykBuniX
  • 152
  • 5