React学习日记

组件化方面

1.模块化:是从代码的角度来进行分析的,把一些可复用的代码,抽离为单个的模块;便于项目的开发与维护
2.组件化:是从UI界面的角度来进行分析,把一些可以复用的UI元素,抽离为单独的组件,便于项目的开发与维护
3.React是如何实现组件化的:React中有组件化概念,但是,并不是像Vue这样的组件模版文件,在React中,一切都是以JS来表现的。

React中的几个核心的概念

虚拟DOM

DOM和虚拟DOM的区别:

  • DOM:浏览器中,提供的概念;用JS对象,表示页面上的元素,并提供操作元素的API
  • 虚拟DOM:是框架中的概念;开发框架中的程序员手动用JS对象来模拟DOM元素和嵌套关系;

本质:用js对象来模拟DOM元素和嵌套关系;
目的:就是为了实现页面元素的高效更新;

Diff算法

  • tree diff:新旧两颗DOM树,逐层对比的过程,就是Tree Diff,当整颗DOM逐层对比完毕,则所有需要按需更新的元素,必然能够找到;
  • componet diif:在进行Tree Diff 的时候,每一层中,组件级别的对比,叫做Component Diff;
  • 如果对比前后,组件的类型相同,则暂认为此组件不需要更新
  • 如果对比后,组件类型不同,则需要移除旧组件,创建新组件,并追加到页面上
  • element diff:在进行组件对比的时候,如果两个组件类型相同,则需要进行元素级别的对比,这叫做Element Diff;
    Diff算法

在项目中使用react

1.运行npm i react react-dom

  • react:专门用于创建组件和虚拟DOM的,同时组件的生命周期都在这个包中

  • react-dom:专门进行DOM操作,最主要的应用场景,就是ReactDOM.render()

2.中index.html页面中,创建容器

<div id=“app”></div>

3.在index.js导入包:

import React from 'react';//创建组件、虚拟DOM元素,生命周期
import ReactDOM from 'react-dom';//把创建好的 组件和虚拟DOM放在页面上展示的。

4.创建虚拟DOM元素:

// 这是一个创建<h1 title="啊,五环" id="myh1">子节点</h1>
// 第一个参数 创建的标签名称
// 第二个参数 元素的属性
// 第三个参数 字节点
const myh1=React.createElement('h1',{title:'啊,五环',id:"myh1"},'子节点')

5.渲染:

ReactDOM.render(
    myh1,//要渲染的虚拟DOM对象
    document.getElementById('app')//指定容器
);

使用JSX语法

1.使用Babel转译器会把JSX转换成一个名为React.createElement()的方法调用。
配置Babel后可直接这样使用

const mytext="你好"
ReactDOM.render(
    <h1>{mytext}</h1>,//要渲染的虚拟DOM对象
    document.getElementById('app')//指定容器
);

2.jsx语法的本质:并不是直接渲染到页面上,而是内部通过Babel内部转换createElement形式,再渲染的
3.在jsx中混合写入js表达式:要把JS代码写到{}
4.在jsx中写注释推荐使用:{/*注释*/}
5.为jsx中的元素添加class类名:需要用className来替代classhtmlFor替换label的for属性

将组件单独抽离出为.jsx文件

新建Hello.jsx文件

export  default function Hello(){ //导出
    return <div>这是Hello组件</div>
}

在index.js 中引入 即可使用

import Hello from "@/Hello"; //省略后缀名,是在webpack.config.js里面配置了,默认补全
  • 可以在webpack.config.js通过alias配置@代表src路径
 alias: {
        '@':path.join(__dirname,'../src'), //表示@为根目录中src的这一层路径
        }

React的组件定义与使用

通过函数定义

function Hello(){
    return <div>这是Hello组件</div>
}
ReactDOM.render(
    <Hello/>,
    document.getElementById('root')
);

为组件传递数据:

function Hello(props){
    console.log(props)
    return <div>这是Hello组件 ---{props.name}</div>
}
ReactDOM.render(
    <Hello name='张三' />,
    document.getElementById('root')
);

通过ES6类class来定义

class Hello extends React.Component {
    render() {
        return (
            <div className="Hello">
            这是Hello组件
            </div>
        );
    }
}
ReactDOM.render(
    <Hello/>,
    document.getElementById('root')
);

通过class 创建的组件中,如果想使用外界传过来的props参数,不需要接收,直接通过this.props.xxx访问即可

三大核心属性1.state

class Square extends React.Component {
    constructor(props) {
        super(props);
        this.state={
            value:undefined,
        }
    }
    btnClick(){
      this.setState({value:'x'})
    };
    render() {
        return (
            <button  onClick={ ()=>this.props.onClick()} className="square">
                {this.props.value}
            </button>
        );
    }
}

三大核心属性2.props

//props是只读的

三大核心属性3.refs与事件处理

1.refs的基础使用(字符串形式的ref不建议使用,建议使用回调函数的refs)

//ref 的使用,
export  default  class Refs extends React.Comp1onent {
     ShowInputVal=()=>{
        console.log(this.refs.myInput.value)
    }

    render(){
        return (<div>
            <input ref="myInput" />
            <button onClick={this.ShowInputVal}>获取inpnt的值</button>
        </div>)
    }
}

2.回调形式的的refs

export default class Refs extends React.Component {
    ShowInputVal = () => {
        console.log(this.myInput.value)
    }

    render() {

        return (<div>
            <input ref={(node)=>{this.myInput=node}} />
            <button onClick={this.ShowInputVal}>获取inpnt的值</button>
        </div>)
    }
}

3.createRef

export default class Refs extends React.Component {
    //React.createRef() 调用后可以返回一个容器,该容器可以存储ref被标记的节点,该容器是'专人专用'的
    myRef=React.createRef()
    ShowInputVal = () => {
        console.log(this.myRef.current.value)
    }

    render() {

        return (<div>
            <input ref={this.myRef} />
            <button onClick={this.ShowInputVal}>获取inpnt的值</button>
        </div>)
    }
}

事件处理
(1)通过onxxx属性指定事件处理函数
(2)通过event.targetdet得到发生事件等DOM元素对象
高阶函数


    savaFormData=(val)=>{
        //必须给一个函数给onChange作为回调
        return (event)=>{
          console.log(event.targetdet.value)
        }
    }
    //必须给一个函数给onChange作为回调
   <input  onChange={this.savaFormData('username')}   ref={this.myRef} />

两种创建组件的方式对比

注意:使用class创建的组件,有自己的私有数据(this.state)和生命周期函数;
使用function创建的组件,只有props,没有自己的私有数据和生命周期函数;

1.用构造函数创建出来的组件:叫做“无状态组件”
2.用class创建的组件:叫做"有状态组件"
3.什么情况下使用有状态组件?什么情况下使用无状态组件?

  • 如果一个组件需要有自己的私有数据,则推荐使用:class创建的有状态组件;
  • 如果一个组件不需要有私有数据,则推荐使用:无状态组件;
  • React官方说:无状态组件,由于没有自己的state和生命周期函数,所以运行效率高

有状态组件和无状态组件的本质区别就是:有无state属性和有无生命周期函数

生命周期

1.初始化阶段:由ReactDOM.render()触发–初次渲染

  1. constructor() //构造器
  2. componentWillMount() // 组件将要挂载
  3. render()
  4. componentDidMount() //组件完成挂载

2.更新阶段:由组件内部this.setSate()或父组件render触发

  1. shouldComponentUpdate() //控制组件更新的阀门钩子
  2. componentWillUpdate() //组件将要更新
  3. render()
  4. componentDidUpdate() //组件更新完毕

3.卸载组件

  1. componentWillUnmount() //卸载组件钩子
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值