反应组件渲染两次?

时间:2020-05-03 11:56:05

标签: javascript reactjs

  1. 我有一个应用程序组件和测试组件。
  2. 我已经在应用程序和应用程序的渲染方法中添加了console.log 测试组件。
  3. 我可以看到应用程序控制台只渲染了一次,但是测试 组件呈现两次。
  4. 此外,我在测试组件中有一个具有受控输入的表单,但作为 当我开始在输入字段中输入内容时。测试组件 重新渲染两次。
  5. 我希望它仅在状态更改一次后才重新渲染一次 按键
  6. 我已经附上了相同的codeandbox示例 https://codesandbox.io/s/funny-tree-dltoc

应用程序组件

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>
  );
}

测试组件:

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]

2 个答案:

答案 0 :(得分:1)

我认为这是因为codeandbox使用react devtools。我发现一个封闭的问题

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

因为在其他环境中,我们只有一个console.log

这是@ ravibagul91的演示

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

答案 1 :(得分:0)

因此,由于useState挂钩的使用,导致第二次呈现测试组件。您的组件需要保持最新状态,因此每次状态更改时都必须重新渲染。您已经拥有handleChange函数,该函数将触发每个输入更改,此函数正在更改状态并且组件会重新渲染。基本上这就是反应的原理。 希望我能帮到你。