React -- 构建用户界面的 JavaScript 库


React – 顶层API
React – DOM文档
React – Babel

介绍

  • React 是一个 JavaScript 库 – 最受欢迎的库之一
    -React 不是一个框架(与 Angular 不同,后者更 opinionated (倾向性))。
  • React 用于在前端构建用户界面(UI)
    -React 是 MVC(Model View Controller,模型视图控制) 应用程序的视图 层。

React 最重要的一个方面是可以创建 components(组件),类似于自定义,可重用的HTML元素,可以快速高效地构建用户界面。
React 还利用 state(状态) 和 props(属性) 简化了数据的存储和处理方式。

设置 和 安装

静态HTML文件

设置安装方式与jQuery类似

创建 index.html 文件;
在头部加载三个 CDN 文件- React,React DOM 和 Babel ;
创建id为rootdiv元素
创建script标签存储自定义代码

<!doctype html>
<html>
 
<head>
    <meta charset="utf-8">
 
    <title>Hello React!</title>
 
    <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
    <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
    <script src="https://unpkg.com/babel-standalone@6.26.0/babel.js"></script>
</head>
 
<body>
 
    <div id="root"></div>
 
    <script type="text/babel">
        // React 代码将放在这里
    </script>
 
</body>
 
</html>

使用ES6类创建React组件

创建组件:

class App extends React.Component {
   //...
}

添加 render() 方法,这是类组件中唯一必须的方法,用于渲染 DOM 节点

class App extends React.Component {
    render() { 
        return (
           //...
           <h1>Hello React!</h1>
        ); 
    } 
}

注:在 return 内部 ,看起来像一个简单的 HTML 元素。我们不需要在此处返回 String 类型的字符串,因此请不要使用引号将元素括起来。这里的内容被称为 JSX

渲染组件到DOM

使用 React DOM 的 render() 方法将我们创建的 App 类渲染到 HTML 中的 id 为 root 的 div 元素中

ReactDOM.render(<App />, document.getElementById('root'));

完整代码

<!doctype html>
<html>
 
<head>
    <meta charset="utf-8">
 
    <title>Hello React!</title>
 
    <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
    <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
    <script src="https://unpkg.com/babel-standalone@6.26.0/babel.js"></script>
</head>
 
<body>
 
    <div id="root"></div>
 
    <script type="text/babel">
        class App extends React.Component { 
            render() { 
                return (
                    <h1>Hello world!</h1>
                ); 
            } 
        } 
 
        ReactDOM.render(<App />, document.getElementById('root'));
    </script>
 
</body>
 
</html>

create-react-app

安装

npx create-react-app react-tutorial

创建并启动

cd react-tutorial
npm start

打开网址:localhost:3000

项目结构

存在项目:/public 和 /src 目录,以及常规的 node_modules,.gitignore,README.md 和 package.json
在这里插入图片描述
注:
在 /public 中,重要文件是 index.html,它与我们之前制作的静态 index.html 文件非常相似 – 只是一个 root div。 在这里,index.html 文件中没有加载任何库或脚本。/src 目录将包含我们所有的 React 代码。
/src/App.js修改后重新加载,环境会自动编译和更新react代码

开发人员工具

React Developer Tools 扩展

安装后,当您打开开发人员工具时,将看到 React 的选项卡。
单击它,您将能够在编写组件时对其进行检查。 您仍然可以转到 Elements 选项卡以查看实际的 DOM 输出。 现在看起来似乎不太合适,但随着应用程序变得越来越复杂,使用它将变得越来越必要。

组件(Components)

React 中的几乎所有内容都由组件组成,组件可以是 class components(类组件)或 simple components(简单组件,注普遍的叫法为 functional components ,也就是函数式组件)。

大多数 React 应用程序都有许多小组件,所有内容都加载到主 App 组件中。

示例

index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="theme-color" content="#000000" />
    <meta
      name="description"
      content="Web site created using create-react-app"
    />
    <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
    <!--
      manifest.json provides metadata used when your web app is installed on a
      user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
    -->
    <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
    <!--
      Notice the use of %PUBLIC_URL% in the tags above.
      It will be replaced with the URL of the `public` folder during the build.
      Only files inside the `public` folder can be referenced from the HTML.

      Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
      work correctly both with client-side routing and a non-root public URL.
      Learn how to configure a non-root public URL by running `npm run build`.
    -->
    <title>React App</title>
  </head>
  <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
    <!--
      This HTML file is a template.
      If you open it directly in the browser, you will see an empty page.

      You can add webfonts, meta tags, or analytics to this file.
      The build step will place the bundled scripts into the <body> tag.

      To begin the development, run `npm start` or `yarn start`.
      To create a production bundle, use `npm run build` or `yarn build`.
    -->
  </body>
</html>

index.js

import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App.js";

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

App.js

import React, {Component} from 'react';
 
class App extends Component {
    render() {
        return (
            <div className="App">
                <h1>Hello, React!</h1>
            </div>
        );
    }
}
 
export default App;

类组件

创建 table.js 并用数据填充,该js创建了一个表格

import React, {Component} from 'react';
 
class Table extends Component {
    render() {
        return (
            <table>
                <thead>
                    <tr>
                        <th>Name</th>
                        <th>Job</th>
                    </tr>
                </thead>
                <tbody>
                    <tr>
                        <td>Charlie</td>
                        <td>Janitor</td>
                    </tr>
                    <tr>
                        <td>Mac</td>
                        <td>Bouncer</td>
                    </tr>
                    <tr>
                        <td>Dee</td>
                        <td>Aspiring actress</td>
                    </tr>
                    <tr>
                        <td>Dennis</td>
                        <td>Bartender</td>
                    </tr>
                </tbody>
            </table>
        );
    }
}
 
export default Table;

将table加载到APP中

import React, { Component } from "react";
import Table from "./Table.js";
class App extends Component {
  render() {
    return (
      <div className="container">
        <Table />
      </div>
    );
  }
}

export default App;

在这里插入图片描述

函数式组件(Functional Components)

该组件是一个函数
组件不使用class关键字

箭头函数创建

表头

const TableHeader = () => { 
    return (
        <thead>
            <tr>
                <th>Name</th>
                <th>Job</th>
            </tr>
        </thead>
    );
}

表体

const TableBody = () => { 
    return (
        <tbody>
            <tr>
                <td>Charlie</td>
                <td>Janitor</td>
            </tr>
            <tr>
                <td>Mac</td>
                <td>Bouncer</td>
            </tr>
            <tr>
                <td>Dee</td>
                <td>Aspiring actress</td>
            </tr>
            <tr>
                <td>Dennis</td>
                <td>Bartender</td>
            </tr>
        </tbody>
    );
}

table 类:

class Table extends Component {
    render() {
        return (
            <table>
                <TableHeader />
                <TableBody />
            </table>
        );
    }
}

组件可以嵌套到其他组件中,并且可以混合函数式组件和类组件

注:类组件必须包含render方法吗,切return只能返回一个父元素

functional components(函数式组件)和 class components(类组件)

functional components(函数式组件):

const SimpleComponent = () => { 
    return <div>Example</div>;
}

class components(类组件)

class ClassComponent extends Component {
    render() {
        return <div>Example</div>;
    }
}

注:当return内容包含在一行中,则不需要用花括号括起来

Props(属性)

Props属性被react用来处理数据
props(属性) 是将现有数据传递给 React 组件的有效方法,但是组件不能更改 props(属性) – 它们是只读的

步骤:

1)删除TableBody组件中硬编码的数据

const TableBody = () => { 
    return <tbody></tbody>;
}

2)创建由对象组成的数组,并在render中创建数组

class App extends Component {
    render() {
        const characters = [
            {
                'name': 'Charlie',
                'job': 'Janitor'
            },
            {
                'name': 'Mac',
                'job': 'Bouncer'
            },
            {
                'name': 'Dee',
                'job': 'Aspring actress'
            },
            {
                'name': 'Dennis',
                'job': 'Bartender'
            }
        ];
 
        return (
            <div className="container">
                <Table />
            </div>
        );
    }
}

3)使用属性将数据传递给子组件

return (
    <div className="container">
        <Table characterData={characters} />
    </div>
);

注:只要属性名称不是保留关键字,就可以随意使用;数据传递要使用花括号,因为是JavaScript表达式
4)在子组件中访问数据

class Table extends Component {
    render() {
        const { characterData } = this.props;
 
        return (
            <table>
                <TableHeader />
                <TableBody characterData={characterData} />
            </table>
        );
    }
}

数据已经绑定在TableBody上
在这里插入图片描述
5)使用this.props.characterData 来读取该数据

const TableBody = props => { 
    const rows = props.characterData.map((row, index) => {
        return (
            <tr key={index}>
                <td>{row.name}</td>
                <td>{row.job}</td>
            </tr>
        );
    });
 
    return <tbody>{rows}</tbody>;
}

注:
为每个 table row(表行) 添加了一个键索引
在 React 中创建列表时应始终使用 keys ,因为它们有助于识别每个列表项

注意:
props(属性) 是将现有数据传递给 React 组件的有效方法,但是组件不能更改 props(属性) – 它们是只读的

State(状态)

state(状态)可以被视为任何不必添加到数据库中又应该保存和修改的数据。

删除数据项

步骤:

1)创建state(状态对象)

class App extends Component {
    state = {};

注:该对象包含要在state(状态)中存储的所有内容的属性

2)将数据存入state对象

     state ={
            characters: [
                {
                    'name': 'Charlie',
                    'job': 'Janitor'
                },
                {
                    'name': 'Mac',
                    'job': 'Bouncer'
                },
                {
                    'name': 'Dee',
                    'job': 'Aspring actress'
                },
                {
                    'name': 'Dennis',
                    'job': 'Bartender'
                }
            ]
        };

3)要操作数据,需要在父类(APP)上创建一个removeCharacter方法(该方法用于删除信息)

removeCharacter = index => {
    const { characters } = this.state;
 
    this.setState({
        characters: characters.filter((character, i) => { 
            return i !== index;
        })
    });
}

注:
filter 不会改变原来的数组,而是创建一个新数组,并且是在 JavaScript 中修改数组的首选方法。
4)将函数传递给组件(将removeCharacter作为prop属性传递给table)

render() {
        return (
            <div className="container">
                <Table
                    characterData={this.state.characters}
                    removeCharacter={this.removeCharacter} 
                />
            </div>
        );
    }

5)修改table

class Table extends Component {
    render() {
        const { characterData, removeCharacter } = this.props;
 
        return (
            <table>
                <TableHeader />
                <TableBody 
                    characterData={characterData} 
                    removeCharacter={removeCharacter} 
                />
            </table>
        );
    }
}

6)创建按钮设置删除

<tr key={index}>
    <td>{row.name}</td>
    <td>{row.job}</td>
    <td><button onClick={() => props.removeCharacter(index)}>Delete</button></td>
</tr>

在这里插入图片描述

提交表格数据(添加数据项)

步骤:
1)从 state.characters 中删除所有硬编码数据

class App extends Component {
    state = {
        characters: []
    };

2)创建Form文件并创建form组件
form.js

import React, { Component } from 'react';
 
class Form extends Component {
    constructor(props) {
        super(props);
 
        this.initialState = {
            name: '',
            job: ''
        };
 
        this.state = this.initialState;
    }
}

注:
表单的目标是每次在表单中更改字段时更新 Form 的 state(状态) ,并且当我们提交时,所有数据将传递到 App 的 state(状态) 中,然后将更新 Table 组件。

3)创建每次输入更改时运行的函数。
event 将被传递,我们将 Form 的 state(状态) 设置为输入的 name(键)和 value 。

handleChange = event => {
    const {name, value} = event.target;
 
    this.setState({
        [name] : value
    });
}

4)在 render() 方法中,让我们从 state(状态) 中获取两个属性,并将它们指定为对应于适当形式键的值。我们将运行 handleChange() 方法作为 input 的 onChange ,最后 export(导出) Form 组件。

render() {
    const { name, job } = this.state; 
 
    return (
        <form>
            <label>Name</label>
            <input 
                type="text" 
                name="name" 
                value={name} 
                onChange={this.handleChange} />
            <label>Job</label>
            <input 
                type="text" 
                name="job" 
                value={job} 
                onChange={this.handleChange}/>
        </form>
    );
}
 
export default Form;

5)在APP中,表格下方渲染表单

return (
    <div className="container">
        <Table
            characterData={characters}
            removeCharacter={this.removeCharacter}
        />
        <Form />
    </div>
);

6)在App中创建提交函数
该函数将使用现有的this.state.characters 并使用 ES6 展开运算符(ES6 spread operator 添加新的 character 参数来更新 state(状态)

handleSubmit = character => {
    this.setState({characters: [...this.state.characters, character]});
}

并将该方法作为参数传递给form

<Form handleSubmit={this.handleSubmit} />

7)在form中创建提交方法
创建一个名为 submitForm() 的方法,该方法将调用 handleSubmit 函数,并将 Form 的 state(状态) 作为我们之前定义的 character 参数传递。它还会将 state(状态) 重置为初始 state(状态) ,以便在提交后清除表单。
提交函数:

submitForm = () => {
    this.props.handleSubmit(this.state);
    this.setState(this.initialState);
}

提交按钮

 <input 
    type="button" 
    value="Submit" 
    onClick={this.submitForm} />

在这里插入图片描述

引入API数据

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值