React组件化的封装

1. 组件化封装的结构

  • 1.1. 定义一个类(组件名必须是大写,小写会被认为是html元素), 继续自React.Component

  • 1.2. 实现当前组件的render函数

    • render当中返回的jsx内容,就是之后React会帮助我们渲染的内容
  • 1.3. 结构图如下:

    js 复制代码
      data 
    
      方法
    
      render() // 具体渲染的内容

2. 组件化-数据依赖

组件化问题:数据在那里定义

  • 2.1. 在组件中的数据,可以分成两类:
    • 参与界面更新的数据:当数据变化时,需要更新组件渲染的内容
    • 不参与界面更新的数据:当数据变化时,不需要更新组件渲染的内容
  • 2.2. 参与姐妹更新的数据又称为参与数据流,这个数据定义在当前对象的state
    • 在构造函数中this.state = { 定义的数据 }
    • 当数据发生变化时,可以调用this.setState({更新的数据})来更新数据,并且通知React进行update操作
      • 在进行update操作时,就会重新调用render函数,并且使用最新的数据,来渲染界面。

3. 组件化-事件绑定

  • 3.1. 组件化问题二: ·事件绑定中的this·
    • 类中直接定义一个函数,并且将这个函数绑定到元素的onClick事件上,当前这个函数的this指向是undefined
  • 3.2. 默认情况下是undefined:(因为在babel转化成严格模式或者ES6语法中类是严格模式严格模式下,this指向undefined)
    • 很奇怪,居然是undefined
    • 因为在正常的DOM操作中,监听点击,监听函数中的this指向其实节点对象(比如说button对象)
    • 这次因为React并不是直接渲染成真实的DOM编写的button只是一个语法糖,它的本质是React的Element对象
    • 那么在这里发生监听时,react在执行函数时并没有绑定this, 默认情况下就是一个undefined
  • 3.3. 在绑定的函数中,可能想要使用当前对象,比如执行this.setState函数,就必须拿到当前对象的this
    • 就需要在传入函数时,给这个函数绑定this

    • 类似于

      javascript 复制代码
           constructor(props) {
              super()
              this.state = {
                message: 'hello World'
              }
              // 对需要绑定的方法,提前绑定好this
              this.btnClick = this.btnClick.bind(this)
      
            }
          {/* 写法一:bind(this) */}
          {/* <button onClick={this.btnClick.bind(this)}>修改文本</button> */}
          {/* 写法二:统一在构造函数中绑定this, 函数调用的时候不用bind(this) */} 
           <button onClick={this.btnClick}>修改文本</button>

4. React数据事件处理

  • 4.1. 如果原生DOM有一个监听事件,我们可以如何操作
    • 方式一:获取DOM原生,添加监听事件
    • 方式二:在HTML原生中,直接绑定onclick;
  • 4.2. 在React中是如何操作呢?React的事件监听,主要有两点不同:
    • React事件的命名采用小驼峰式(camelCase), 而不是纯小写
    • 需要通过{}传入一个事件处理函数,这个函数会在事件发生时被执行;

5. React组件的分类重构代码

  • 5.1. 组件分为:类组件和函数组件
    • 类组件: class App extends React.Component

      js 复制代码
            class App extends React.Component {
              constructor () {
                super()
                this.state = {
                  message: 'hello world',
                  counter: 100
                }
              }
        
              render () {
                const  { message } = this.state
                return  (
                  <div>
                    <h2>{ message }</h2>
                  </div>
                )
              }
            }```
    • 函数组件:

      js 复制代码
        function App() {
          return (
            <div className="App">
              <header className="App-header">
                <img src={logo} className="App-logo" alt="logo" />
                <p>
                  Edit <code>src/App.js</code> and save to reload.
                </p>
                <a
                  className="App-link"
                  href="https://reactjs.org"
                  target="_blank"
                  rel="noopener noreferrer"
                >
                  Learn React
                </a>
              </header>
            </div>
          );
        }
        export default App;  

5. 编写Hello_React案例

  • 5.1. 第一步:在界面上通过React显示一个Hello World

    • 注意:编写React的script代码中,必须添加type="text/babel", 作用是可以让babel解析jsx的语法
    • 完整代码如下:
    javascript 复制代码
      <script type="text/babel">
        const root = ReactDOM.createRoot(document.querySelector('#root'))
        // 将文本定义成变量
        let message = 'hello World'
        const root = ReactDOM.createRoot(document.querySelector('#root'))
        root.render(<h2>{message}/h2>)
      </script>
    • 5.2. ReactDOM.createRoot函数:用于创建一个React根,之后的渲染的内容会包含在这个根中。

      • 参数:将渲染的内容,挂载到哪个HTML元素上
        • 根元素id为root的元素
    • 5.3. root.render()

      • 参数:要渲染的根组件
    • 5.4. 完整代码:

      javascript 复制代码
        <!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>
      
          <!-- 1. CDN引入 -->
          <script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
          <script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
          <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
      
      
      
          <!-- 2. 编写React代码 -->
          <script type="text/babel">
            const root = ReactDOM.createRoot(document.querySelector('#root'))
            // 将文本定义成变量
            let message = 'hello World'
            // 监听按钮的点击
            function btnClick () {  
              // 1.1 修改数据
              message = '你好啊 李银河'
              // 1.2. 重新渲染界面(原因:React默认情况下不会重新执行渲染界面的, React是没有黑魔法的,黑魔法:所有东西都是可见的)
              rootRender()
            }
      
            // 3. 封装一个渲染函数
            function rootRender () {
              // 使用()把所有的html括号包裹起来,代表的是一个整体
              root.render((
                <div>
                  <h1>{message}</h1>
                  <button onClick={btnClick}>修改文本</button>  
                </div>
              ))
            }
            rootRender()
      
          </script>
          
      
        </body>
        </html>

6. 使用组件重构代码

  • 6.1 完整代码如下:
js 复制代码
  <!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="../lib/react.js"></script>
   <script src="../lib/react-dom.js"></script>
   <script src="../lib/babel.js"></script>
 
   <script type="text/babel">
     // 1.定义App根组件
     class App extends React.Component {
       constructor () {
         super()
         this.state = {
           message: 'hello world',
           counter: 100
         }
       }
 
       render () {
         const  { message } = this.state
         return  (
           <div>
             <h2>{ message }</h2>
           </div>
         )
       }
     }
     // 2. 创建root并且渲染App组件
     const root = ReactDOM.createRoot(document.querySelector('#root'))
     root.render(<App/>)
   </script>
 </body>
 </html>  
相关推荐
AI视觉网奇13 分钟前
音频获取长度
java·前端·python
小喷友1 小时前
第 6 章:API 路由(后端能力)
前端·react.js·next.js
zwjapple1 小时前
Next.js 中使用 MongoDB 完整指南
开发语言·javascript·mongodb
像素之间1 小时前
elementui中rules的validator 用法
前端·javascript·elementui
小高0071 小时前
🚀把 async/await 拆成 4 块乐高!面试官当场鼓掌👏
前端·javascript·面试
CF14年老兵1 小时前
SQL 是什么?初学者完全指南
前端·后端·sql
2401_837088501 小时前
AJAX快速入门 - 四个核心步骤
前端·javascript·ajax
一月是个猫1 小时前
前端工程化之Lint工具链
前端
小潘同学1 小时前
less 和 sass的区别
前端
无羡仙1 小时前
当点击链接不再刷新页面
前端·javascript·html