Skip to content

4 Component

4.1 Overview

组件就是自定义的 HTML标签,React 采用它来构建用户界面。

Screenshot 2025-01-25 at 10.48.47

React 中的组件就是页面中的一小块区域,在组件中会包含这块区域中的视图代码、样式代码、逻辑代码,以自定义标签的形式使用。

Screenshot 2025-01-25 at 10.49.01

Screenshot 2025-01-25 at 10.49.30

组件使开发者拥有复用 UI 的能力。定义一次,到处使用。

我们可以将组件看成是 Javascript 中的函数,因为组件和函数的设计思想是一致的,函数用来封装重复代码,复用重复代码。组件用来封装用户界面中的重复区块,复用重复区块。用户界面中的任何一个元素或者任何一块区域都可以被封装成组件的形式。

Screenshot 2025-01-25 at 11.02.34

Screenshot 2025-01-25 at 11.02.46

通过组件可以将一个庞大的用户界面拆分成若干个小的组件,每个组件默认都是隔离的状态,意味着组件与组件之间的代码不会发生冲突,修改一个组件中的代码不会影响到另外的组件,方便代码维护。

4.2 Basic

在React 中组件以函数的形式存在,组件最基本的特征就是一个返回视图(JSX)的函数。

function Paragraph() {
    return <p>Hello, React Component</p>
}

注意:组件名称首字母必须大写。

在React 中,组件以标签的形式进行调用。

ReactDOM.render(<Paragraph />, document.getElementById("root"))
const jsx = (
    <>
    <Paragraph />
    <Paragraph />
    </>
)
ReactDOM.render(jsx, document.getElementById("root"))
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="root"></div>
    <script src="https://cdn.bootcdn.net/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/@babel/standalone@7.13.17/babel.min.js"></script>
    <script type="text/babel">
        function Paragraph() {
            return <p>Hello, Component!</p>;
        }
        ReactDOM.render(<Paragraph />, document.getElementById('root'));
    </script>

</html>

Screenshot 2025-01-25 at 10.46.18

Screenshot 2025-01-25 at 10.46.32

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="root"></div>
    <script src="https://cdn.bootcdn.net/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/@babel/standalone@7.13.17/babel.min.js"></script>
    <script type="text/babel">
        function Paragraph() {
            return <p>Hello, Component!</p>;
        }
        ReactDOM.render(<>
            <Paragraph />
            <Paragraph />
        </>, document.getElementById('root'));
    </script>

</html>

Screenshot 2025-01-25 at 10.47.14

Screenshot 2025-01-25 at 10.47.32

组件和 HTML一样,都是以树状结构存在的。

Screenshot 2025-01-25 at 11.05.44

        function TextOne() {
            return <b>I am a TextOne Component</b>;
        }
        function TextTwo() {
            return <b>I am a TextTwo Component</b>;
        }
        function Paragraph() {
            return (
                <p>
                    <TextOne />
                    <TextTwo />
                </p>
            );
        }
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="root"></div>
    <script src="https://cdn.bootcdn.net/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/@babel/standalone@7.13.17/babel.min.js"></script>
    <script type="text/babel">
        function TextOne() {
            return <b>I am a TextOne Component</b>;
        }
        function TextTwo() {
            return <b>I am a TextTwo Component</b>;
        }
        function Paragraph() {
            return (
                <p>
                    <TextOne />
                    <TextTwo />
                </p>
            );
        }
        ReactDOM.render(<Paragraph />, document.getElementById("root"));
    </script>

</html>    

Screenshot 2025-01-25 at 11.15.05

Screenshot 2025-01-25 at 11.14.57

4.3 Component Properties

4.3.1概述

在调用组件时,可以通过为组件标签添加属性的方式向组件内部传递数据,实现复用组件的差异化。

<Person name="张三" sex="/>

Screenshot 2025-01-25 at 11.17.52

4.3.2 基本用法

<Paragraph msg="I am first" />
<Paragraph msg="I am second" />

在组件内部,使用组件函数参数的方式接受外部传递进来的数据,组件函数的第一个参数为对象,存储了所有外部通过属性的方式传递进来的数据。

function Paragraph(props) {
    return <p>{props.msg}</p>
}
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="root"></div>
    <script src="https://cdn.bootcdn.net/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/@babel/standalone@7.13.17/babel.min.js"></script>
    <script type="text/babel">
        function Paragraph(props) {
            return (
                <p>
                    {props.msg}
                </p>
            );
        }
        ReactDOM.render(
            <>
                <Paragraph msg="I am first" />
                <Paragraph msg="I am second" />
            </>,
            document.getElementById("root"));
    </script>

</html>

Screenshot 2025-01-25 at 11.23.21

Screenshot 2025-01-25 at 11.23.28

4.3.3 设置组件属性默认值

function Person(props){
    return (
    <div>
      {props.info.name}
      {props.info.age}
    </div>
  )
}
// 报错:在调用 Person 组件时由于没有传递 info 属性对象,导致组件内部代码在执行时报错
<Person />

// 正常运行
<Person info={{name: "sam", age: 20}} /> // 外层大括号 插值语法的括号
Person.defaultProps = {
    info: {}
}

Screenshot 2025-01-25 at 11.30.49

Screenshot 2025-01-25 at 11.31.00

Screenshot 2025-01-25 at 11.31.48

Screenshot 2025-01-25 at 11.32.03

Screenshot 2025-01-25 at 11.33.18

Screenshot 2025-01-25 at 11.33.38

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="root"></div>
    <script src="https://cdn.bootcdn.net/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/@babel/standalone@7.13.17/babel.min.js"></script>
    <script type="text/babel">
        function Person(props) {
            return (
                <div>
                    {props.info.name}
                    {props.info.age}
                </div>
            );
        }
        Person.defaultProps = {
            info: {},
        };
        ReactDOM.render(<Person />, document.getElementById("root"));
    </script>

</html>

4.4 children

4.4.1 Using Component Children

<Person> Hello, React children </Person>
<Person>
    <p>single child</p>
</Person>
<Person>
    <p>multiple child</p>
  <p>multiple child</p>
  <p>multiple child</p>
</Person>
function Person(props) {
   return <div> {props.children} </div>
}
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="root"></div>
    <script src="https://cdn.bootcdn.net/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/@babel/standalone@7.13.17/babel.min.js"></script>
    <script type="text/babel">
        function Person(props) {
            return (
                <div>
                    {props.children}
                </div>
            );
        }

        ReactDOM.render(
            <>
                <Person> Hello, React children </Person>
                <Person>
                    <p>single child</p>
                </Person>
                <Person>
                    <p>multiple child</p>
                    <p>multiple child</p>
                    <p>multiple child</p>
                </Person>
            </>,
            document.getElementById("root")
        );
    </script>

</html>

Screenshot 2025-01-25 at 11.39.31

Screenshot 2025-01-25 at 11.39.18

4.4.2 Applications of Component Children

Screenshot 2025-01-25 at 11.44.25

页面布局容器

function HomePage() {
    return <div>HomePage</ div>;
}
function AboutPage() {
    return <div>AboutPage</ div>;
}
function Header() {
    return <div>Header</div>;
}
function Footer(){
  return <div>Footer</div>;
}
function Layout(props) {
    return (
        <>
        <Header /> 
    <div>{props.children}</div>
    <Footer />
    </>
  );
}
function HomePage()) {
    return <Layout>HomePage</Layout>;
}
function AboutPage() {
    return <Layout>AboutPage</Layout>;
}

Screenshot 2025-01-25 at 12.00.38

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="root"></div>
    <script src="https://cdn.bootcdn.net/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/@babel/standalone@7.13.17/babel.min.js"></script>
    <script type="text/babel">

        function Header() {
            return <div>Header</div>;
        }
        function Footer() {
            return <div>Footer</div>;
        }

        function Layout(props) {
            return (
                <>
                    <Header />
                    <div>{props.children}</div>
                    <Footer />
                </>
            );
        }


        function HomePage() {
            return <Layout>HomePage</Layout>;
        }
        function AboutPage() {
            return <Layout>AboutPage</Layout>;
        }

        ReactDOM.render(
            <HomePage />,
            document.getElementById("root")
        );
    </script>

</html>

Screenshot 2025-01-25 at 12.00.46

Screenshot 2025-01-25 at 12.01.21

Screenshot 2025-01-25 at 12.01.27