React 基础 day01

React 与 Vue 对比

  • 什么是模块化: 从代码的角度, 去分析问题, 把我们编程的业务逻辑, 分割到不同的模块中进行开发, 这样能够方便代码的重用 ;

  • 什么是组件化: 从 UI 的角度去分析问题, 把一个页面拆分为一些互不相干的小组件, 随着项目的开发, 手里的组件会越来越多, 最后如果要实现一个页面, 可能直接把现有的组件那过来进行拼接, 就能快速得到一个完整的组件, 这样方便了 UI 组件的重用 ;
  • Vue如何实现组件化: .vue 模板文件, 浏览器不识别, 在运行前会预先编译成真正的组件
  • React如何实现组件化: 直接使用 JS 代码的形式, 去创建你想要的组件

React 中几个核心概念

虚拟Dom (Virtual Document Object Model)
  • DOM的本质是什么: 就是用 JS 表示的 UI 元素 ;
  • DOM和虚拟DOM的区别:
    • DOM是浏览器中JS提供功能, 所以只能使用浏览器提供固定的 API 操控 ;
    • 虚拟DOM并不是由浏览器提供的, 而是我们手动模拟实现的, 类似于浏览器中的DOM, 但是有着本质的区别 ;
  • 为什么要实现虚拟DOM: 为了实现DOM节点的高效更新 ;

创建 React 项目

安装相关包

// 这个包是专门用来创建 React 组件, 组件生命周期等
npm install react -S
// 这个里面主要封装了和 DOM 操作相关的包, 比如要把组件渲染到页面上
npm install react-dom -S
// main.js 中导入相关的包
import React from 'react';
import ReactDOM from 'react-dom';
// createElement() 创建虚拟DOM对象, 至少接收3个参数
// 1. string 要创建的类型 2. 属性对象, 创建的元素身上有哪些属性 3. 后面可以放多个, 表示这个DOM对象的子节点
var myDiv = React.createElement('div', {id: 'this is div'}, '这是一个div');
// 1. 要渲染的DOM元素, 2. 要渲染到哪个位置
ReactDOM.render('myDiv', document.getElementById('app'));

JSX 语法的基本使用和原理

从上面可以看出如果一直使用这种方式创建 DOM 元素太麻烦了, 所以 React 官方提供了一套 JSX 语法规范, 能够在 js 文件中, 书写类似于 HTML 那样的代码, 快速定义虚拟 DOM 结构 ;

JSX( 符合 XML 规范的 JS 语法 ), JSX 在内部运行的时候, 也是把类似于 HTML 这样的标签代码, 转换为 React.createElement() 的形式 ; 再渲染到页面中 ( JSX 是一个对程序员友好的语法糖 ) ;

var myTitle = 'this is title';
// 如果需要使用 js 语法, 就用 {} 去解析
var myDiv = <div>
这是一个div
<h3 title={ mytitle }>JSX 真好用...</h3>
</div>

在 JSX 中, 如果要为元素添加 class 属性, 必须写成 className ; 与之类似的还有 label 标签的 for 属性, 要写成 htmlFor 因为 for class 都属于 js 中的关键字 ;

注意 : 以上代码是不能直接在 js 文件中使用的, 需要安装相关的语法转换工具

npm install babel-preset-react -D
// 在 .babelrc 文件中的 presets 项中, 添加 "react"
presets: ["react"]

创建最基本的组件

使用构造函数创建组件
/**
 * 在 react 构造函数就是一个最基本的组件
 * 可以把组件的名称, 以HTML标签的形式引入页面中渲染组件
 * React在解析所有标签的时候, 是以标签的首字母区分的, 如果首字母小写, 按照普通的HTML标签解析, 如果首字母大写, 按照组件的形式解析
 */
var person = {
  name: 'ls',
  age: 22,
  address: '...'
};
function Hello (props) {
  // 如果什么都不渲染, return null
  return <div>
    <h3>这是通过组件渲染出来的标签</h3>
    {/* 如果想要接收外部的参数 必须显示的给组件定义一个props参数 */}
    <p>{ props.name }</p>
  </div>
}
ReactDOM.render(<div>
  {/* es6 中的属性扩散 */}
  <Hello { ...person }></Hello>
  {/* <Hello name = { person.name } age = { person.age }></Hello> */}
</div>, document.getElementById('app'));
使用 class 创建组件
// Hello 继承自 React.Component
class Hello extends React.Component {
  constructor(props) {
    super(props);
    // 在组件的 constructor 构造器中, 不能使用this.props取值, 只能通过给constructor显示的加一个props参数才可以
    console.log(props.name)
  }
  // 内部必须有一个 render() 函数
  render () {
    // 必须return一个内容, 如果不需要就 return null
    return <div>
      <h3>这是通过 class 创建的组件</h3>
      // class内部不用定义 props参数, 可以直接通过 this. 的方式访问
      <p>{ this.props.name } -- { this.props.age }</p>
    </div>
  }
}
ReactDOM.render(<div>
  <Hello name="zs" age={20}></Hello>
</div>, document.getElementById('app'));

以上创建组件的两种方式, 有着本质的区别 ;

使用 function 构造函数创建的组件 ( 无状态组件 ):

  • 内部没有 state 私有数据, 只有一个 props 来接收外界传递过来的数据 ;
  • function 创建的组件中没有自己的生命周期函数

使用 class 关键字创建的组件 ( 有状态组件 ) :

  • 内部除了有 props 接收数据外, 还有一个专门存放自己私有数据的 this.state 属性, 这个 state 是可读可写的

那么这两种组件分别在什么时候用呢 ?

  1. 如果一个组件需要存放自己的私有数据或者需要在组件的不同阶段执行不同的业务逻辑, 此时就适合使用有状态组件 ;
  2. 如果一个组件只需要根据外界传递过来的 props, 渲染固定的页面, 就非常适合 无状态组件 ; ( 次组件由于剔除了生命周期函数, 所以, 运行速度会相对来说快一些 ) ;
抽离组件

新建一个 js/jsx 文件, 把构造函数放进去, 然后通过 export default Hello 的方式暴露一个对象 ;

  • JSX 文件 配置 loader

    module: {
      rules: [
        // 用 js 一样的loader 正则变化一下而已
        { test: /\.jsx?$/, use: 'babel-loader', exclude: /node_modules/ }
      ]
    }
  • 在 main 文件中导入后即可使用

猜你喜欢

转载自www.cnblogs.com/article-record/p/12185406.html
今日推荐