My App

组件实例

组件实例

在 React 中有一个重要的概念很少被讨论:每当我们在 React 中渲染一个组件时,我们就会创建一个组件实例。

关于组件实例的在线信息很多都非常过时;这个主题上最受欢迎的博客文章是 2016 年的!自那时以来,React 发生了很多变化,文章中提到的许多内容现在已经不再真实。

让我们深入探讨一下。

这是视频中的第一个沙盒,最简单的 React 应用:

import React from 'react';
import { createRoot } from 'react-dom/client';

function RandomNumber() {
  const [num, setNum] = React.useState(0);

  return (
    <button onClick={() => setNum(Math.random())}>
      Current number: {num}
    </button>
  );
}

const root = createRoot(document.querySelector('#root'));
root.render(
  <>
    <RandomNumber />
  </>
);

…这是视频中的第二个沙盒,一个更复杂的应用程序,带有可切换的页脚。

import React from 'react';

function App() {
  const [
    includeFooter,
    setIncludeFooter,
  ] = React.useState(false);

  return (
    <>
      <h1>Some Application</h1>
      <form className="footer-toggle-wrapper">
        <input
          type="checkbox"
          id="footer-toggle"
          checked={includeFooter}
          onChange={(event) => {
            setIncludeFooter(event.target.checked);
          }}
        />
        <label htmlFor="footer-toggle">
          Toggle Footer
        </label>
      </form>
      {includeFooter && <Footer />}
    </>
  );
}

function Footer() {
  const [
    backgroundColor,
    setBackgroundColor,
  ] = React.useState('#232538');

  return (
    <footer style={{ backgroundColor }}>
      <form>
        <label htmlFor="bg-picker">
          Tweak background:
        </label>
        <input
          type="color"
          id="bg-picker"
          value={backgroundColor}
          onChange={(event) => {
            setBackgroundColor(event.target.value);
          }}
        />
      </form>
      <p>
        © Some Application Inc., 1998-present. All
        Rights Reserved.
      </p>
    </footer>
  );
}

export default App;

元素不创建实例,渲染才会创建

假设我们有以下代码:

import React from "react";
 
function Counter({ initialValue = 0 }) {
  const [count, setCount] = React.useState(initialValue);
 
  return <button onClick={() => setCount(count + 1)}>{count}</button>;
}
 
const elem = <Counter initialValue={10} />;
 
console.log(elem);

我们正在创建一个 <Counter /> 元素,但我们并没有对其进行任何操作。因此, Counter 组件实际上不会被渲染。将不会有组件实例,没有 count 状态变量,什么都没有。

元素是我们想要创建的描述。在这种情况下,我们正在描述一个 Counter ,其初始值为 10 :

{
  type: ƒ Counter,
  key: null,
  ref: null,
  props: {
    initialValue: 10
  },
  _owner: null,
  _store: {}
}

为了创建一个组件实例,我们必须渲染它:

import { createRoot } from "react-dom/client";
 
const root = createRoot(document.querySelector("#root"));
root.render(<Counter initialValue={10} />);

我们将这个 <Counter /> 描述传递给 React,以便 React 可以将其实现。React 渲染 Counter 组件,在此过程中创建实例,并将 {{2 }} 添加到 DOM 中。

在我们日常使用 React 的工作中,容易忘记这是所有 React 应用的根。它属于那种“设置好后就忘了”的东西,不需要任何维护。但从根本上说,React 元素在我们将它们传递给 React 进行渲染之前并不会做任何事情。