应用:

知乎网站
image.png

分类:

reactWeb reactNative reactVR
react - 图2

与vue的对比:

  1. react灵活性和协作性更好,适用于大型项目
  2. Vue.js有着丰富的API(如v-if),实现起来更简单快速

    项目结构:

    public:

  • favicon.ico:项目图标
  • index.html:首页模板文件
  • mainifest.json:移动端配置文件
  • robots.txt:存放于网站根目录下的ASCII编码的文本文件,它通常告诉网络搜索引擎的漫游器(又称网络蜘蛛),此网站中的哪些内容是不应被搜索引擎获取的,哪些是可以被获取的

    src:

  1. index.js:项目的入口文件
  2. index.css:index.js的样式文件
  3. app.js:相当于一个方法模块(app.css)
  4. serviceWorker.js: 这个是用于写移动端开发的,PWA必须用到这个文件,有了这个文件,就相当于有了离线浏览的功能。

    JSX语法:

  5. JSX=Javascript + XML。React发明了JSX,可以方便的利用HTML语法来创建虚拟DOM,当遇到<,JSX就当作HTML解析,遇到{就当JavaScript解析.

  6. 自定义的组件必须首写字母要进行大写,而JSX是小写字母开头的
  7. JSX语法默认情况下最外层只能有一个组件
  8. 如需要外层有多个组件可以使用Fragment标签,
    1. import React from 'react'
    2. const Fragment=React.Fragment
    3. <Fragment>
    4. <header className="App-header">
    5. this is react
    6. </header>
    7. <ComponentX name="自定义组件"/>
    8. </Fragment>

react设计模式:

  1. constructor,super(),state,setState
  2. 方法:

    1. <input value={this.state.name} onChange={this.changeContent.bind(this)}/>
  3. class的方法里面的this指向该对象的实例,如没有则指向指向该方法运行时所在的环境,但是类和模块的内部,默认就是严格模式,this指向undefined,所以需要手动绑定,如果是向子组件传入方法则此时this指向父组件的props对象

  4. react是单向数据流,不支持数据双向绑定,需要事件驱动
  5. 箭头函数里函数体用()包裹则自动默认返回函数体的内容,{}包裹则只是普通函数
  6. 不允许直接改变或直接操作state,后期优化会产生很大的性能障碍

数组的扩展运算符

扩展运算符:把list数组进行了分解,形成了新的数组,然后再进行组合
在用map循环时,需要设置一个不同的key值

  1. addList(){
  2. this.setState({
  3. list:[...this.state.list,this.state.name]
  4. })
  5. }

jsx代码采坑:

  • 注释:{/ 注释 /}
  • css类名:
  • html解析:dangerouslySetInnerHTML={{__html:item}}
  • label标签和input框绑定,用htmlFor代替for


父子组件传值:

  • 父组件向子组件传递内容,靠属性props的形式传递。

    1. //====================父组件代码=========================
    2. <ul>
    3. {
    4. this.state.list.map((item,index)=>(
    5. <li className="red" key={item} onClick={this.delItem.bind(this,index)}>
    6. {item}<XiaoItem content={item}/>
    7. </li>)
    8. )
    9. }
    10. </ul>
    11. //================子组件=====================
    12. import React, { Component } from 'react';
    13. class xiaoItem extends Component{
    14. render(){
    15. return <div>{this.props.content}</div>
    16. }
    17. }
    18. export default xiaoItem
  • 子组件向父组件传递数据

    • 子组件时不能操作父组件里的数据的,所以需要借助一个父组件的方法,来修改父组件的内容
    • 子组件使用父组件的方法
      • 子组件先通过props获取到需要的参数和父组件的方法
      • 在子组件中新建一个方法,在这个方法中调用上一步获取到的父组件的方法
        1. //=======================子组件===============
        2. import React, { Component } from 'react';
        3. class xiaoItem extends Component{
        4. handleClick(){
        5. this.props.delItem(this.props.idx)
        6. }
        7. render(){
        8. return <div onClick={this.handleClick.bind(this)}>{this.props.content}</div>
        9. }
        10. }
        11. export default xiaoItem
        12. //===================父组件=================
        13. <ul>
        14. {
        15. this.state.list.map((item,index)=>(
        16. <li className="red" key={item+index} >
        17. <XiaoItem content={item} idx={index} delItem={this.delItem.bind(this)}/>
        18. </li>
        19. ))
        20. }
        21. </ul>

        单向数据流:

        1. 单向数据流

  • props属性是只读的,不能在子组件中强行改变

  • 如果子组件被调用多次的话,props属性修改会影响所有的被调用的子组件,所以react采用了单向数据流

    2. react是否和其他框架结合使用

    • 可以,react只渲染了模板文件里的root元素
    • 可以在其他地方使用其他框架如jquery

      3. 函数式编程:

      每一个函数代表着一个功能,代码清晰,同时也便于前端自动化测试

props校验:

  1. 导入PropTypes: import PropTypes from 'prop-types'
  2. 配置特定的 propTypes 属性

    xiaoItem.propTypes={
     content:PropTypes.string,
     delItem:PropTypes.func,
     index:PropTypes.number
    }
    
  3. 使用默认的属性值defaultProps:

    XiaojiejieItem.defaultProps = {
     name:'松岛枫'
    }
    

    ref的使用:

    作用:加强语义化

    addList(){
     this.setState({
         list:[...this.state.list,this.state.inputValue],
         inputValue:''
         //关键代码--------------start
     },()=>{
         console.log(this.ul.querySelectorAll('div').length)
     })
     //关键代码--------------end
    }
    

    react生命周期:

    生命周期函数:指在某一个时刻组件会自动调用执行的函数
    react - 图3

Initialization阶段:

定义属性props和状态state

Mounting阶段:

伴随着整个虚拟DOM的生成

  • componentWillMount:在组件即将被挂载到页面的时刻执行,只在页面刷新时执行一次
  • render:组件挂载中,页面state或props发生变化时执行
  • componentDidMount:组件挂载完成时被执行,只在页面刷新时执行一次

    Updatation阶段:

    原因:
  1. props改变
  2. state改变

    小周期一:

  • shouldComponentUpdate:在组件更新之前,自动被执行
  • componentWillUpdate:在组件更新之前,但shouldComponenUpdate之后被执行。但是如果shouldComponentUpdate返回false,这个函数就不会被执行,后面的内容也都不会执行。
  • componentDidUpdate:在组件更新之后执行

    小周期二:

  • componentWillReceiveProps:子组件接收到父组件传递过来的参数,父组件render函数重新被执行,这个生命周期就会被执行。这个组件第一次存在于Dom中,函数是不会被执行的;如果已经存在于Dom中,函数才会被执行

Unmounting阶段:

  • componentWillUnmount:组件去除时执行

生命周期函数改善性能:

问题:输入的过程中子组件频繁渲染
解决方法:

shouldComponentUpdate(nextProps,nextState){
  //nextProps是变化后的属性,state是变化后的状态
  if(nextProps.content!==this.props.content){
    return true
  }else{
    return false
  }
}

React中的动画:

与css3结合

class Boss extends Component {
    constructor(props) {
        super(props);
        this.state = { 
            isShow:false
        }
    }
    callHim(){
        var isShow=this.state.isShow
        this.setState({
            isShow:!isShow
        })
    }
    render() { 
        return (
            <div>
                <div className={this.state.isShow?'show':'hide'}>BOSS级角色:孙悟空</div>
                <div><button onClick={this.callHim.bind(this)}>点击</button></div>
            </div>
        );
    }
}
//============================样式============
.show{ opacity: 1; transition:all 1.5s ease-in;}
.hide{opacity: 0; transition:all 1.5s ease-in;}

keyframes:

.hide{
    animation: hide-item 2s ease-in-out forwards;
}
.show{
    animation: show-item 2s ease-in-out forwards;
}
@keyframes hide-item{
    0%{
        opacity: 1;
        color: yellow;
    }
    50%{
        opacity: 0.5;
        color: red;
    }
    100%{
        opacity: 0;
        color: green;
    }
}
@keyframes show-item{
    0%{
        opacity: 0;
        color: green;
    }
    50%{
        opacity: 0.5;
        color: red;
    }
    100%{
        opacity: 1;
        color: yellow;
    }
}

动画库:react-transition-group

三个组件库:

  • Transition
  • CSSTransition
  • TransitionGroup

    CSSTransition

  1. 引入CSSTransition import {CSSTransition} from 'react-transition-group'
  2. 添加标签

    <CSSTransition
     in={this.state.isShow}
     timeout={2000}
     classNames="boss-text">
    <div className={this.state.isShow?'show':'hide'}>BOSS级角色:孙悟空</div>
    </CSSTransition>
    
  3. 添加css

  • xxx-enter: 进入(入场)前的CSS样式;
  • xxx-enter-active:进入动画直到完成时之前的CSS样式;
  • xxx-enter-done:进入完成时的CSS样式;
  • xxx-exit:退出(出场)前的CSS样式;
  • xxx-exit-active:退出动画知道完成时之前的的CSS样式。
  • xxx-exit-done:退出完成时的CSS样式。 ```css .input {border:3px solid #ae7000}

.boss-text-enter{ opacity: 0; } .boss-text-enter-active{ opacity: 1; transition: opacity 2000ms;

} .boss-text-enter-done{ opacity: 1; } .boss-text-exit{ opacity: 1; } .boss-text-exit-active{ opacity: 0; transition: opacity 2000ms;

} .boss-text-exit-done{ opacity: 0; } ```

  1. unmountOnExit属性

在元素退场时,自动把DOM也删除。