美文网首页让前端飞前端全栈开发
简单介绍JSX语法和组件概念以及生命周期

简单介绍JSX语法和组件概念以及生命周期

作者: a333661d6d6e | 来源:发表于2018-10-03 20:24 被阅读11次

    JSX

    image.png
    React中,推出了一种新的语法取名为JSX,它给了JS中写HTML标签的能力,不需要加引号。JSX的语法看起来是一种模板,然而它在编译以后,会转成JS语法,只是书写过程中的语法糖。

    JSX的解析器会帮我们读取这种语法并加以处理。

    下面是一个简单的例子。

    const element = <h1 className="greeting">Hello, world!</h1>;
    

    其实相当于如下的代码:

    const element = React.createElement({
     'h1',
     {className: 'greeting'},
     'Hello, world!',
     'Xxx'
    })
    
    

    第一个参数是类型,可以是HTML标签,也可以是React组件;第二个参数是props对象;第三个以后参数是children,会按照传入顺序依次排列。

    当然第三个参数也可以传入数组,如果第三个参数传入数组,则后面再传入其他子节点,就会报错。

    JSX提供了一种HTML和JS混合编写的能力。在需要使用JS表达式的地方,用一组花括号包裹起来即可:

    function formatName(user) {
     return user.firstName + ' ' + user.lastName;
    }
    const user = {
     firstName: 'Harper',
     lastName: 'Perez'
    };
    const element = (
     <h1 className="test">
     Hello, {formatName(user)}!
     </h1>
    );
    ReactDOM.render(
     element,
     document.getElementById('app')
    );
    

    由于class在js中关键字,所以使用className去替代。

    上面说到了JSX其实是语法糖,所以如果要循环嵌入列表,可以直接将列表传进来:

    
    
    const listItems = numbers.map((number) =>
     <li>{number}</li>
    );
    ReactDOM.render(
     <ul>{listItems}</ul>,
     document.getElementById('app')
    );
    
    

    在控制台中会看到这样的报错:

    warning.js:33 Warning: Each child in an array or iterator should have a unique "key" prop.
    

    这是由于react使用virtual dom来渲染真实节点,在列表渲染时,如果每个item没有对应的key,react处理起增删改时就会很慢,所以,渲染列表时,最好给每一个item增加一个唯一的key。

    const listItems = numbers.map((number, index) =>
     <li key={index}>{number}</li>
    );
    

    组件
    React中最重要的概念就是组件。

    Conceptually, components are like JavaScript functions. They accept arbitrary inputs (called “props”) and return React elements describing what should appear on the screen.
    

    组件可以看做是一个函数,指定了输入(props),就会给出输出(一个React元素)。

    创建组件有两种方法:

    1.函数

    function Welcome(props) {
     return <h1>Hello, {props.name}</h1>;
    }
    

    2.es6的类

    class Welcome extends React.Component {
     render() {
     return <h1>Hello, {this.props.name}</h1>;
     }
    }
    

    第二种方法创建的组件,可以拥有内部状态(state)和生命周期函数。

    如果只是展示信息,没有复杂的操作,可以选择第一种函数方法。如果组件比较复杂,并且需要在不同的时期做初始化或者销毁等工作,就要采用第二种ES6类方法。

    状态(State)

    State类似于props,但它是组件私有的并且完全由组件控制。

    下面我们结合一个Clock类来演示State的概念。

    import React, {Component} from 'react';
    export default class Clock extends Component {
     constructor(props) {
     super(props);
     this.state = {date: new Date()};
     }
     render() {
     return (
     <div>
     <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
     </div>
     );
     }
    }
    

    在这个组件里,Clock就拥有了自己的状态,而不是从外界发生传入。接下来我们增加一个定时器的功能,来引入生命周期。

    import React, {Component} from 'react';
    export default class Clock extends Component {
     ...
     componentDidMount() {
     this.timerID = setInterval(
     () => this.tick(),
     1000
     );
     }
     componentWillUnmount() {
     clearInterval(this.timerID)
     }
     tick () {
     this.setState({date: new Date()})
     }
     ...
    }
    

    注意:在React中,调用setState方法去修改state,会触发View视图层的修改,直接设置state就不会触发state的修改。

    上面引入了两个生命周期方法:componentDidMount , componentWillUnmount 。
    componentDidMount 会在组件挂载到DOM节点上之后触发,而 componentWillUnmount 会在组件从节点上移除以后触发。
    React还有很多生命周期方法,下面做一个详细的说明。
    生命周期
    在React中,一个组件可能会经历创建、挂载、更新、卸载、销毁这些事件,React为我们提供了钩子函数来在这些事件触发时进行操作。
    他的生命周期可以分为三大部分:
    创建、更新、销毁。
    创建组件并将其插入DOM时,下面的方法会依次触发

    constructor()
    static getDerivedStateFromProps()
    render()
    componentDidMount()
    

    更新时,将会触发

    static getDerivedStateFromProps()
    shouldComponentUpdate()
    render()
    getSnapshotBeforeUpdate()
    componentDidUpdate()
    

    卸载时,触发

    componentWillUnmount()
    

    为了更加直观的查看生命周期方法,可以参考这张图:


    image.png

    Render阶段,把一些state和props计算执行。

    Commit阶段就是把React组件插入到真实DOM节点上,这个时候可以使用DOM。

    而Pre-commit阶段就是在插入真实DOM之前,这个阶段可以读取DOM。

    创建时

    constructor

    1.用来初始化props和state。

    2.是唯一可以直接修改state的地方。

    getDerivedStateFromProps

    1.当state需要从props初始化时使用

    2.尽量不要使用:因为维护两者的一致会增加复杂度

    3.每次render前都会被调用

    4.典型场景:表单控件获取默认值

    render

    不能缺少的,它实际上决定了组件到底要渲染成什么样子。

    componentDidMount

    1.在UI渲染完成之后触发

    2.只执行一次

    3.通常在这个方法里触发Ajax请求等操作。

    更新时

    有三种情况会触发update。

    props发生了改变,setState执行,forceUpdate执行。

    forceUpdate

    前两种不多说,第三个forceUpdate触发的场景比较少见,如果Render方法使用了props和state以外的数据,就需要这个方法。

    这里是一个例子。

    shouldComponentUpdate

    1.决定virtual dom是否会重绘

    2.一般可以用pure component自动实现

    3.这个方法用来做性能优化相关的操作。有的时候state和props的更新其实不会影响dom的展示,没有必要再次渲染DOM。

    getSnapshotBeforeUpdate

    1.更新DOM前被触发,state已经更新

    2.它可以将之前DOM的状态传递给componentDidUpdate,然后进行计算处理后更新DOM。

    这里一个例子。

    componentDidUpdate

    1.每次UI更新后都会调用

    2.props或者state修改后都会触发

    卸载时

    这个阶段只会触发一个方法。

    componentWillUnmount

    1.只调用一次

    2.可以在这个方法里清除计时器,关闭一些连接等。

    以上是JSX、组件概念、props、state、生命周期的介绍。
    本次给大家推荐一个最后给大家推荐一个免费的学习群,里面概括移动应用网站开发,css,html,webpack,vue node angular以及面试资源等。
    对web开发技术感兴趣的同学,欢迎加入Q群:864305860,不管你是小白还是大牛我都欢迎,还有大牛整理的一套高效率学习路线和教程与您免费分享,同时每天更新视频资料。
    最后,祝大家早日学有所成,拿到满意offer,快速升职加薪,走上人生巅峰。

    相关文章

      网友评论

        本文标题:简单介绍JSX语法和组件概念以及生命周期

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