React学习2

1.propTypes

2.defaultProps

3.state、prop、render

当组件的state或者props发生改变的时候,render函数就会重新执行。

当父组件的render函数被运行时,它的子组件的render都将被重新运行一次。

4.虚拟DOM

React代码中render下的JSX内容:JSX —> React.createElement —> 虚拟DOM(JS对象)—> 真实的DOM

//JSX语法
render() {
        return(
            <div>item</div>
        )
    }

//JSX底层实现是通过createElement转换成虚拟DOM的
//createElement语法,也可以实现渲染页面,但这种写法没有JSX简便
render() {
        return(
            React.createElement('div', {}, 'item')
        )
    }

(1)第一种方案

1.准备state 数据

2.生成JSX 模板

3.数据 + 模板 结合,生成真是的DOM,来显示

4.state 发生改变

5.数据 + 模板 结合,生成真实的DOM,替换原始的DOM

缺陷:第一次生成一个完整DOM片段;第二次生成一个完整DOM片段;第二次的DOM替换第一次DOM,非常耗性能。

(2)第二种方案

1.state 数据

2.JSX 模板

3.数据 + 模板 结合,生成真是的DOM,来显示

4.state 发生改变

5.数据 + 模板 结合,生成真实的DOM,并不直接替换原始的DOM

6.新的DOM(DocumentFragment---文档碎片,js底层的,存在于内存中)和原始的DOM 作比对,找差异。

7.(假设找出input框发生了变化)

8.只用新的DOM中的有变化的元素(input元素),替换掉老的DOM中的旧元素(input元素)

缺陷:性能提升并不明显(对比也消耗性能)

(3)第三种方案---虚拟DOM

1.state 数据

2.JSX 模板

3.数据 + 模板 结合,生成虚拟DOM(虚拟DOM就是一个js对象,用它来描述真实DOM)(1.节点标签;2.节点属性;3.节点的子节点 / 内容)

['div', {id: 'abc'}, ['span', {}, 'hello world']]

4.用虚拟DOM的结构生成真是的DOM,来显示 

<div id='abc'><span>hello world</span></div>

5.state发生变化

6.数据 + 模板 生成新的虚拟DOM(损耗:生成真实DOM > 虚拟DOM)

['div', {id: 'abc'}, ['span', {}, 'bye bye']]

7.比较原始虚拟DOM 和 新的虚拟DOM的区别(采用DIff算法),找到区别是span中的内容

8.直接操作DOM,改变span中的内容。

原因:在js中操作js对象(生成虚拟DOM,比较虚拟DOM)所耗性能 远小于 操作真实的DOM。

优点:

(1)性能提升来了;

(2)它使得跨端应用得以实现。React Native。

原生应用中不支持DOM,但支持虚拟DOM,可以把虚拟DOM转化成原生应用中的组件。

5.Diff算法(Different):同层比对(算法简单,速度快)

在jsx中做循环时(比如map循环返回新数组、子组件时),对循环中的每一项(最外层的)都要赋予一个唯一的、稳定的key值。有利于虚拟DOM比较过程,key值是Diff算法中的一部分。

不要用index作为key值,因为index有可能会改变,不稳定(比如删除数组中的一个元素时)。

6.React中ref(reference)的使用:在react中直接获取DOM元素。(尽量不用)

如果想要在setState更新完,再获取DOM时,需要注意setState是异步执行的(2)。

7.setState的异步执行

(1)当在短时间内,连续多次调用setState变更数据时,react将几次setState调用合并为一次,只进行一次数据更新、虚拟DOM对比、页面渲染。

(2)setState不会立即执行,setState的第二个参数也是一个函数,该函数表示为当setState执行完后再执行的函数,需要保证在setState后执行的内容,放在该函数体内。

8.生命周期

见本地“红点工厂”

使用场景:

(1)合理使用shouldComponentUpdate();

shouldComponentUpdate(nextProps, nextState){
        if(nextProps.content !== this.props.content){
            return true;
        }else{
            return false;
        }
    }

(2)Ajax异步请求放在componentDidMount()中;利用axios扩展工具进行ajax请求的发送。

         使用前先进行安装axios,命令:npm install axios

import axios from 'axios';

    //使用Charles进行接口数据模拟
    //向地址/api/todolist,发送ajax请求,显示在list中
    componentDidMount() {
        axios.get('/api/todolist').then((res) => {   //数据请求成功后
            this.setState(()=>{
                return {
                    list: [...res.data]
                }
            })
        }).catch(() => {   //数据请求失败后
            alert('error')
        })
    }

ajax请求的是服务端的数据,在没有服务端数据时,可以在本地使用Charles进行接口数据模拟。

9.React的CSS动画(可以实现简单的动画,但有局限)(简单了解)

(1)App.js

import React, {Component, Fragment} from "react";
import AppStyle from './AppStyle.css';

class App extends Component {
    constructor(props){
        super(props)
        this.state={
            show: true
        }
        this.handleToggle=this.handleToggle.bind(this)
    }
    render() {
        return (
            <Fragment>
                <div className={this.state.show ? 'show' : 'hide'}>hello</div>
                <button onClick={this.handleToggle}>toggle</button>
            </Fragment>
        )
    }

    handleToggle(){
        this.setState(()=>{
            return{
                show: this.state.show ? false : true
            }
        })
    }
}
export default App;

(2.1)AppStyle.css(过渡动画)

.show{
    opacity: 1;
    transition: all 1s ease-in;
}

.hide{
    opacity: 0;
    transition: all 1s ease-in;
}

(2.2)AppStyle.css(动画效果)

.show{
    animation: show-item 2s ease-in forwards;
}

.hide{
    animation: hide-item 2s ease-in forwards;
}

@keyframes show-item {
    0% {
        opacity: 0;
        color: blue;
    }
    50% {
        opacity: 0.5;
        color: green;
    }
    100% {
        opacity: 1;
        color: red;
    }
}

@keyframes hide-item {
    0% {
        opacity: 1;
        color: red;
    }
    50% {
        opacity: 0.5;
        color: green;
    }
    100% {
        opacity: 0;
        color: blue;
    }
}

10.使用react-transition-group实现动画(可实现更复杂的)
文档位置:GitHubhttps://github.com/reactjs/react-transition-group)> 进入Main documentation > 进入Components中的CSSTransition或其他组件

实例如下所示:

(1)App.js

import React, {Component, Fragment} from "react";
import { CSSTransition } from 'react-transition-group';  //动画组件
import AppStyle from './AppStyle.css';

class App extends Component {
    constructor(props){
        super(props)
        this.state={
            show: true
        }
        this.handleToggle=this.handleToggle.bind(this)
    }
    render() {
        return (
            <Fragment>
                <CSSTransition in={this.state.show}
                               timeout={1000}
                               classNames="fade"
                               unmountOnExit
                               onEnter={(el) => {el.style.color='blue'}}
                               appear={true}>
                    <div>hello</div>
                </CSSTransition>
                <button onClick={this.handleToggle}>toggle</button>
            </Fragment>
        )
    }

    handleToggle(){
        this.setState(()=>{
            return{
                show: this.state.show ? false : true
            }
        })
    }
}
export default App;

(2)AppStyle.css

.fade-enter,fade-appear{
    opacity: 0;
}
.fade-enter-active,fade-appear-active{
    opacity: 1;
    transition: opacity 1s ease-in;
}
.fade-enter-done,fade-appear-done{
    opacity: 1;
}

.fade-exit{
    opacity: 1;
}
.fade-exit-active{
    opacity: 0;
    transition: opacity 1s ease-in;
}
.fade-exit-done{
    opacity: 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值