• React 详解


    1、React简介

    React官网 https://react.docschina.org/

    本人git demo地址:https://gitee.com/lizuoqun/web-react-lzq

    1.1、React的特点

    1. 声明式编码
    2. 组件化编码
    3. React Native 编写原生应用
    4. 高效(优秀的Diffing算法)

    1.2、React高效的原因

    1. 使用虚拟(virtual)DOM, 不总是直接操作页面真实DOM。
    2. DOM Diffing算法, 最小化页面重绘。

    1.3、JSX

    1.3.1、JSX说明

    1. 全称: JavaScript XML
    2. react定义的一种类似于XML的JS扩展语法: JS + XML本质是React.createElement(component, props, ...children)方法的语法糖
    3. 作用: 用来简化创建虚拟DOM
      • 写法:var ele =

        Hello JSX!

      • 注意1:它不是字符串, 也不是HTML/XML标签
      • 注意2:它最终产生的就是一个JS对象
    4. 标签名任意: HTML标签或其它标签
    5. 标签属性任意: HTML标签属性或其它
    6. 基本语法规则
      • 遇到 <开头的代码, 以标签的语法解析: html同名标签转换为html同名元素, 其它标签需要特别解析
      • 遇到以 { 开头的代码,以JS语法解析: 标签中的js表达式必须用{ }包含

    1.3.2、渲染虚拟DOM(元素)

    1. 语法: ReactDOM.render(virtualDOM, containerDOM)
    2. 作用: 将虚拟DOM元素渲染到页面中的真实容器DOM中显示
    3. 参数说明
      • 参数一: 纯js或jsx创建的虚拟dom对象
      • 参数二: 用来包含虚拟DOM元素的真实dom元素对象(一般是一个div)

    2、三大核心属性

    2.1、state状态

    1. state是组件对象最重要的属性, 值是对象(可以包含多个key-value的组合)
    2. 组件被称为"状态机", 通过更新组件的state来更新对应的页面显示(重新渲染组件)

    使用状态数据需要注意:

    1. 组件中render方法中的this为组件实例对象
    2. 组件自定义的方法中this为undefined,如何解决?
      • 强制绑定this: 通过函数对象的bind()
      • 箭头函数
    3. 状态数据,不能直接修改或更新

    案例:定义一个展示天气信息的组件:默认展示天气炎热 或 凉爽,点击文字切换天气

        <script type="text/babel">
          class Num extends React.Component {
            // 借助构造器初始化状态
            constructor(props) {
              super(props);
              this.state = { isOne: true };
              // 绑定this
              this.changeState = this.changeState.bind(this);
            }
            changeState() {
              // 这里的this对象是undefined?
              // console.log(this)
              console.log("change");
              // 状态不能直接更改
              // this.state.isOne = !this.state.isOne;
              // 通过setState方法进行修改值,并且通过这种方法进行设置值,只会覆盖原状态下的键值,其余键值不变
              this.setState({ isOne: !this.state.isOne });
              console.log(this);
            }
            render() {
              // console.log(this);
              // 读取状态进行渲染判断
              return (
                // 绑定事件、初始化渲染时不调用函数
                <h2 onClick={this.changeState}>
                  this is {this.state.isOne ? "one" : "zero"}
                </h2>
              );
            }
          }
          ReactDOM.render(<Num />, document.getElementById("app1"));
        </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    对于这样编写代码来进行实现,还可以对代码进行简化一些:

        <script type="text/babel">
          class Num extends React.Component {
            state = { isOne: true };
            // 自定义方法,指向一个箭头函数,箭头函数内部的this等价于外部第一个的this,也就等于该类的this,故可以直接通过this拿到state
            changeState = () => {
              this.setState({ isOne: !this.state.isOne });
            };
            render() {
              return (
                <h2 onClick={this.changeState}>
                  this is {this.state.isOne ? "one" : "zero"}
                </h2>
              );
            }
          }
          ReactDOM.render(<Num />, document.getElementById("app1"));
        </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    2.2、props数据

    1. 每个组件对象都会有props(properties的简写)属性
    2. 组件标签的所有属性都保存在props中

    props的作用:

    1. 通过标签属性从组件外向组件内传递变化的数据
    2. 注意: 组件内部不要修改props数据

    案例:自定义用来显示一个人员信息的组件

    1. 姓名必须指定,且为字符串类型;
    2. 性别为字符串类型,如果性别没有指定,默认为男
    3. 年龄为字符串类型,且为数字类型,默认值为18
        <script type="text/babel">
          class Person extends React.Component {
            render() {
              console.log(this);
              // props 不可修改
              const { name, age, sex, date } = this.props;
              return (
                <ul>
                  <li>姓名:{name}</li>
                  <li>年龄:{age + 1}</li>
                  <li>性别:{sex}</li>
                  <li>日期:{date}</li>
                </ul>
              );
            }
          }
          // 设置校验规则
          Person.propTypes = {
            name: PropTypes.string.isRequired,
            age: PropTypes.number,
            spack: PropTypes.func,
          };
          // 设置默认值
          Person.defaultProps = {
            sex: "未知",
            date: Date(),
          };
          function spack() {
            console.log("spack...");
          }
          ReactDOM.render(
            <Person name="hyy" age="18" sex="男" spack={spack} />,
            document.getElementById("app")
          );
          const p = { name: "张三", age: 18 };
          ReactDOM.render(<Person {...p} />, document.getElementById("app1"));
          ReactDOM.render(
            <Person name="18" age={18} />,
            document.getElementById("app2")
          );
        </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    还可以通过函数来进行定义组件使用props

        <script type="text/babel">
          function Demo(props) {
            const { name, age, sex, date } = props;
            return (
              <ul>
                <li>姓名:{name}</li>
                <li>年龄:{age}</li>
                <li>性别:{sex}</li>
                <li>日期:{date}</li>
              </ul>
            );
          }
          // 设置校验规则
          Demo.propTypes = {
            name: PropTypes.string.isRequired,
            age: PropTypes.number,
            spack: PropTypes.func,
          };
          // 设置默认值
          Demo.defaultProps = {
            sex: "未知",
            date: Date(),
          };
          const p = { name: "张三", age: 18 };
          ReactDOM.render(<Demo {...p} />, document.getElementById("app1"));
        </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    2.3、ref节点

    组件内的标签可以定义ref属性来标识自己,本质上和给标签定义id是一样的。

    基本使用:

        <script type="text/babel">
          class Demo extends React.Component {
            showData = () => {
              //   const leftInput = document.getElementById("input1").value;
              //   alert(leftInput);
              alert(this.refs.ref1.value);
            };
            blurData = () => {
              alert(this.refs.ref2.value);
            };
            render() {
              return (
                <div>
                  <input
                    ref="ref1"
                    id="input1"
                    type="text"
                    placeholder="点击按钮提示"
                  />
                  <button onClick={this.showData}>提示</button>
                  <input
                    ref="ref2"
                    onBlur={this.blurData}
                    type="text"
                    placeholder="失去焦点提示"
                  />
                </div>
              );
            }
          }
    
          ReactDOM.render(<Demo />, document.getElementById("app"));
        </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    使用回调的ref

        <script type="text/babel">
          class Demo extends React.Component {
            showData = () => {
              alert(this.input1.value);
            };
            blurData = () => {
              alert(this.input2.value);
            };
            render() {
              return (
                <div>
                  <input
                    ref={(currentNode) => {
                      this.input1 = currentNode;
                    }}
                    id="input1"
                    type="text"
                    placeholder="点击按钮提示"
                  />
                  <button onClick={this.showData}>提示</button>
                  <input
                    ref={(currentNode) => {
                      this.input2 = currentNode;
                    }}
                    onBlur={this.blurData}
                    type="text"
                    placeholder="失去焦点提示"
                  />
                </div>
              );
            }
          }
    
          ReactDOM.render(<Demo />, document.getElementById("app"));
        </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    使用createRef API创建

        <script type="text/babel">
          class Demo extends React.Component {
            myRef = React.createRef();
            showData = () => {
              console.log(this.myRef);
              alert(this.myRef.current.value)
            };
    
            render() {
              return (
                <div>
                  <input ref={this.myRef} type="text" placeholder="点击按钮提示" />
                  <button onClick={this.showData}>提示</button>
                </div>
              );
            }
          }
    
          ReactDOM.render(<Demo />, document.getElementById("app"));
        </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    3、React生命周期

    组件的生命周期可分成三个状态:

    Mounting(挂载):已插入真实 DOM
    Updating(更新):正在被重新渲染
    Unmounting(卸载):已移出真实 DOM

    在React16版本之前的生命周期:
    在这里插入图片描述

    1. 初始化阶段: 由ReactDOM.render()触发—初次渲染
      1. constructor()
      2. componentWillMount()
      3. render()
      4. componentDidMount()
    2. 更新阶段: 由组件内部this.setSate()或父组件重新render触发
      1. shouldComponentUpdate()
      2. componentWillUpdate()
      3. render()
      4. componentDidUpdate()
    3. 卸载组件: 由ReactDOM.unmountComponentAtNode()触发
      1. componentWillUnmount()

    在React16版本之后的生命周期:
    在这里插入图片描述

    1. 初始化阶段: 由ReactDOM.render()触发—初次渲染
      1. constructor()
      2. getDerivedStateFromProps
      3. render()
      4. componentDidMount()
    2. 更新阶段: 由组件内部this.setSate()或父组件重新render触发
      1. getDerivedStateFromProps
      2. shouldComponentUpdate()
      3. render()
      4. getSnapshotBeforeUpdate
      5. componentDidUpdate()
    3. 卸载组件: 由ReactDOM.unmountComponentAtNode()触发
      1. componentWillUnmount()

    4、React-Cli

    安装依赖与创建项目

    全局安装
    npm i -g create-react-app
    创建项目
    create-react-app web-lzq-react
    如果安装create-react-app还是无法创建项目可使用以下命令进行操作
    npx create-react-app web-lzq-react
    启动项目
    npm start
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    项目文件目录说明

    文件目录名说明
    public静态资源文件夹
    favicon.icon网站页签图标
    index.html主页面
    logo192.pnglogo图
    logo512.pnglogo图
    manifest.json应用加壳的配置文件
    robots.txt爬虫协议文件
    src源码文件夹
    App.cssApp组件的样式
    App.jsApp组件
    App.test.js用于给App做测试
    index.css样式
    index.js入口文件
    logo.svglogo图
    reportWebVitals.js页面性能分析文件(需要web-vitals库的支持)
    setupTests.js组件单元测试的文件(需要jest-dom库的支持)

    5、React-Router5

    如果你了解vue-router,那么对于react-router来说就相对来说比较容易理解,React Router 是一个用于 React 的全功能客户端和服务器端路由库,它是一个用于构建用户界面的 JavaScript 库。React Router 可以在任何 React 运行的地方运行;在 web 上,在带有 node.js 的服务器上,以及在 React Native 上。

    安装react-router5

    npm install react-router-dom@5
    
    • 1

    5.1、BrowserRouter

    BrowserRouter是在 Web 浏览器中运行 React Router 的推荐界面。A使用干净的 URL 将当前位置存储在浏览器的地址栏中,并使用浏览器的内置历史堆栈进行导航。

    ReactDOM.render(
      <BrowserRouter>
      </BrowserRouter>,
      root
    );
    
    • 1
    • 2
    • 3
    • 4
    • 5

    5.2、Link

    它允许用户通过单击或点击来导航到另一个页面。在react-router-dom中,Link呈现一个可访问的元素,其href指向它链接到的资源。

    <Link to='/home'>Home</Link>
    
    • 1

    5.3、NavLink

    默认情况下,当组件处于活动状态时,active类会被添加到组件中。这为从 v5 升级的大多数用户提供了相同的简单样式机制。简单来说,NavLink和Link的区别就是是否可以用来控制当前选择的路由的样式

    <NavLink className="list-group-item " to="/home/news">
    	News
    </NavLink>
    
    • 1
    • 2
    • 3

    5.4、Navigate

    navigate顾名思义是导航的意思,当元素呈现时就会更改当前位置。

    <Navigate to="/home" />
    
    • 1

    5.5、Router和Routers

    这两个表达的意思就相当于一串的路由数据,当进行页面路由访问的时候还会从上至下进行逐层判断是否跳转

    <Routes>
    	<Route path="/lzq/about" component={About}></Route>
    	<Route path="/lzq/home" component={Home}></Route>
    	<Route path="/about" component={About}></Route>
    </Routes>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    5.6、Redirect

    Redirect 重定向

    <Redirect to="/null"></Redirect>
    
    • 1
  • 相关阅读:
    欢迎 Gemma: Google 最新推出开源大语言模型
    【SpringMVC】| SpringMVC拦截器
    上海交大牵手淘宝成立媒体计算实验室:推动视频超分等关键技术发展
    MySQL面试题:用户金额充值面试题详解
    远程连接服务器
    vue3 项目部署,Nginx配置https,重定向,详细流程
    【数据库07】后端开发必备的大数据知识指南
    c++模板
    跨境分析 | 疫情之下跨境电商如何选品?这类商品亚马逊销量不降反增
    C/C++晶晶赴约会 2020年12月电子学会青少年软件编程(C/C++)等级考试一级真题答案解析
  • 原文地址:https://blog.csdn.net/qq_44973159/article/details/125789349