美文网首页
React入门(二)

React入门(二)

作者: Leonard被注册了 | 来源:发表于2019-11-15 18:55 被阅读0次

组件

1.函数式组件

  • 什么是函数式组件
    创建一个函数,只要函数中返回一个新的JSX元素,则为函数式组件
import React from 'react'
function News(props){    // 声明函数式组件
  console.log(props);    //接收只读属性
  return <div>
    <ul>
      <li>webpack</li>
      <li>vue</li>
      <li>react</li>
    </ul>
  </div>
}
export default News;
  • 调用组件
    可以是单闭合,也可以是双闭合。双闭合方式可以把一些子节点当作属性(children)传递给组件,在组件中可以把传递的这些节点放在指定的位置
// index.js
ReactDOM.render(<>
        <Dialog con='嘿嘿嘿'  />
    <Dialog con='呵呵呵' lx={1} >
          <span>1</span>
          <span>2</span>
    </Dialog>
</>, document.getElementById('root'));
// Dialog.js
export default function Dialog(props) {
    let {con, lx = 0, children, style = {}} = props,
        title = lx === 0 ? '系统提示' : '系统警告';
    return <section style={style}>
        <h2>{title}</h2>
        <div>{con}</div>
        {/*把属性中传递的子元素放到组件中的指定位置*/}
        { children }

        {/*也可以基于REACT中提供的专门遍历CHILDREN的方法来完成遍历操作*/}
        {
            React.Children.map(children, item => item)
        }
    </section>;
};
  • 静态组件
    每次调用函数组件,都会重新进行渲染和计算,把渲染后的结果呈现在页面中,渲染完成后呈现的内容将不再改变,除非重新调用该组件

2.类组件

  • 什么是类组件
    创建一个类,让其继承React.Component或者React.PureComponent,此类被称为类组件
  • 基于状态管理动态组件:
    1.设置初始状态值
    2.修改状态:setState修改组件中的状态
import React from 'react'

export default class Clock extends React.Component{
  // 调取组件,创建类的一个实例,首先执行constructor,把属性、上下文等信息传递进来
  constructor(props){
    super(props);
    // 如果只写SUPER():虽然创建实例的时候把属性传递进来了,但是并没有传递父组件,也就是没有把属性挂载到实例上,使用THIS.PROPS获取的结果是UNDEFINED
    // 如果SUPER(PROPS):在继承父类私有的时候,就把传递的属性挂载到了子类的实例上,CONSTRUCTOR中就可以使用THIS.PROPS了
    console.log(this.props);    // 接收的只读属性
    // 创建初始状态
    this.state = {
      time: new Date().toLocaleString()
    }
  }  
  // render渲染组件的内容  
  render(){
    return <div>
        {this.state.time}
    </div>
  }
  // componentDidMount:生命周期  第一次渲染完
  componentDidMount(){
    setInterval(() => {
            // 修改状态,并且通知组件重新渲染
            this.setState({
                time: new Date().toLocaleString()
            });
    }, 1000);
}
  • 属性的操作
    利用第三方插件prop-types可以设置属性的规则
// test.jsx
import PropTypes from 'prop-types';
...
// 设置默认属性
static defaultProps = {
    m: 100
};
// 属性验证
static propTypes = {
    m: PropTypes.number,
    x: PropTypes.string.isRequired
};
...

// index.js
...
<Clock m={1} x='pass'/>
...
  • 非受控组件
    不受状态管控的组件(通过ref方式),有时我们会需要直接对某个DOM节点或组件进行操作,而不是通过状态,此时会运用到非受控组件,对应的概念:受控组件:受状态管控的组件 => 数据驱动视图渲染
// 以下是三种使用ref的方法
export default class Input extends React.Component {
    constructor(){
      super();
      this.refObj = React.createRef();  // { current: null }    method 3
    }
    render() {
        return <div>
             <input type="text" ref='inpBox' />      // method 1,不推荐使用
             <input type="text" ref={element => {    // method 2
                // element当前的元素对象
                this.inp = element;
             }} /> 
             <input type="text" ref={ this.refObj } />  // method3
        </div>;
    }
    componentDidMount() {
        this.refs.inpBox.focus();  // method 1,不推荐使用
        this.inp.focus();          // method 2
        this.refObj.current.focus();  // method3
    }
}

3.细节知识点

  • REACT中的事件是合成事件,即所有的事件都是进行事件代理的,而且事件对象也是合成的,故会出现以下情况。解决这一问题的方法有两种,一是采用bind改变this指向,二是采用ES6的箭头函数
render(){
  return <div>
    <button onClick={this.handle}>button</button>
  </div>
}
handle(ev){
  console.log(this);    // undefined
  console.log(ev);      // 事件对象
}
<button onClick={this.handle.bind(this)}>button</button>    //method 1
<button onClick={()=>console.log(this)}>button</button>     //method 2
  • 当使用setState进行状态设置时,即使状态不发生变化,仍然会触发render的重新渲染,此时应当考虑对其进行优化,可以在shouldComponentUpdate中进行手动对比设置,也可以直接让类组件继承React.PureComponent来自动进行浅对比(引用变化是检测不出来的)
handle = ev => {
    this.setState({
        // 不管状态是否改变,都会控制render重新渲染
    });
}
// 手动对比优化,与自动对比同时出现时手动为主
shouldComponentUpdate(nextProps, nextState) {
    // 拿当前的状态和最新修改的状态进行对比(浅对比),如果一样则不渲染,不一样才进行渲染
    if (this.state.n === nextState.n) {
        return false;
    }
    return true;
} 

// 自动对比
export default class Test extends React.PureComponent {
  ...
}
...
  • setState本身在生命周期函数或者合成事件中执行是异步的
    =>保证REACT生命周期函数执行的顺序不会紊乱
    =>保证其实现渲染队列的机制,可以合并setState后统一处理
export default class Test1 extends React.Component {
   state = {
       n: 0
   };
   render() {
       console.log("render")
       return <div>
           {this.state.n}
           <button onClick={this.handler}>+</button>
       </div>
   }
   handler = ev => {
       this.setState({
           n: this.state.n + 1
       })
       console.log('ok')
   }
}
点击按钮后
  • setState在原生事件绑定中和其他异步操作中是同步的
    =>此时失去渲染队列的效果
export default class Test1 extends React.Component {
    state = {
        n: 0,
        m: 0
    };
    render() {
        console.log('render')
        return <div>
            {this.state.n} === {this.state.m}
            <button onClick={this.handler}>+</button>
        </div>
    }
    handler = ev => {
        setTimeout(()=>{
            this.setState({
                n: 10
            })
            this.setState({
                m:20
            })
            console.log('ok')
        },1000)
        
    }
}
失去渲染队列处理效果
  • 按理说ES6中的类是不能设置静态属性的,但是WEBPACK打包编译的时候会根据babel-preset-react将其转换为复合规范的语法
// 以下写法理应报错,但是webpack编译后可正常运行
...
static defaultProps = {
    m: 100
};
static propTypes = {
    m: PropTypes.number,
    x: PropTypes.string.isRequired
};
...
  • 通过onChange事件实现MVVM双向绑定
...
<input type="text" className='form-control'
      value={text}
      onChange={ev => {
           this.setState({
                text: ev.target.value
           });
}}/>
...

4.生命周期

1.第一次调用组件渲染的周期流程
1.1.给属性设置默认值(设置默认规则)
1.2.constructor => 设置初始的状态等
1.3.componentWillMount 第一次挂载之前 => 向服务器发送数据请求
1.4.render 渲染
1.5.componentDidMount 第一次挂载之后 => 把虚拟DOM转换为真实DOM了,我们可以获取DOM元素进行操作


2.当组件状态发生改变 setState
2.1.shouldComponentUpdate(nextProps, nextState) 是否允许当前组件重新渲染(返回TRUE则继续重新渲染,返回FALSE则停止重新渲染)
2.2.componentWillUpdate(nextProps, nextState) 重新渲染之前
2.3.render重新渲染
2.4.componentWillUpdate 重新渲染之后


3.当组件属性发生改变:父组件重新传递最新的属性信息
3.1.componentWillReceiveProps(nextProps, nextState) 在接受最新的属性之前
3.2....(重复2)


4.componentWillUnmount 卸载组件之前

export default class Test extends React.Component {
    constructor(props) {
        super(props);
        console.log('constructor');
        this.state = {
            data: [],
            n: 0
        };
    }

    componentWillMount() {
        console.log('componentWillMount');
        setTimeout(() => {
            this.setState({
                data: [100, 200]
            });
        }, 5000);
    }

    render() {
        console.log('render');
        let { data, n } = this.state;
        return <div>
            {data} === {n}
            <button onClick={() => {
                this.forceUpdate();  <!-- 调用该方法时直接跳过shouldComponentUpdate阶段 -->
            }}>强制更新</button>
        </div>;
    }

    componentDidMount() {
        console.log('componentDidMount');
    }

    shouldComponentUpdate(nextProps, nextState) {
        console.log('shouldComponentUpdate', nextProps, nextState);
        // nextProps  nextState 最新要修改的属性和状态
        // this.state / this.props 修改之前的
        // this.forceUpdate() 不会执行这个周期函数,会强制更新当前组件
        return true;
    }

    componentWillUpdate() {
        console.log('componentWillUpdate');
    }

    componentDidUpdate() {
        console.log('componentDidUpdate');
    }
} 

相关文章

  • React Native学习资料

    React 入门实例教程React-Native入门指南Flex 布局教程:语法篇React Native探索(二...

  • react+webpack项目实际开发应用

    react+webpack项目实际开发应用 在《react入门》和《react入门提高》中我讲了,react的基础...

  • react+webpack项目实际开发应用

    react+webpack项目实际开发应用 在《react入门》和《react入门提高》中我讲了,react的基础...

  • react+webpack项目实际开发应用

    react+webpack项目实际开发应用 在《react入门》和《react入门提高》中我讲了,react的基础...

  • React Native:从入门到原理

    React Native:从入门到原理 React Native:从入门到原理

  • React Native

    JavaScript 标准参考教程(alpha)ECMAScript 6入门 React 入门实例教程React ...

  • React 实践(一)

    参考:《React 入门实例教程--阮一峰》、《React 学习教程--众成翻译》。React 框架入门学习摘录。...

  • awesome-react-native

    React React 中文文档一定要看官方文档 React 入门实例教程阮一峰老师出品,最好的 react 入门...

  • React入门(二)

    三、React组件 React 组件基本上是由组件的构建方式、组件内的状态属性与生命周期方法组成 React.cr...

  • (二)react入门

    react使用的是JSX语法,和vue、小程序语法类似 class属性在react中要写成className 创建...

网友评论

      本文标题:React入门(二)

      本文链接:https://www.haomeiwen.com/subject/qjqbbctx.html