美文网首页
React个人整理

React个人整理

作者: chrisghb | 来源:发表于2019-06-12 21:23 被阅读0次
    • React基础
    //ReactDOM.render(reactWhat,domWhere)在浏览器中渲染应用的一种途径
    //React.DOM表示预定义好的HTML元素集合
    //React.DOM.h1(attributes,children)表示一个预定义的React 组件
    //h1()第一个参数接收一个对象,用于指定该组件的任何属性(比如id属性,三个特殊属性class:className,for:htmlFor,style:对象形式赋值)。
    //h1()第二个参数定义了该组件的子元素(Hello world!)
    //document.getElementById("app") 方法访问DOM 节点,告诉React 需要把应用渲染在页面的哪个部分
    ReactDOM.render(React.DOM.h1({
        id: 'my-heading'
    }, 'Hello world!'), document.getElementById('app'));
    
    // JSX版本
    ReactDOM.render(
        <h1 id="my-heading" >
        <span><em>Hell < /em>o</span > world!
        < /h1>,
    document.getElementById('app')
    );
    
    • 自定义新组件
    //自定义新组件
    var Component = React.createClass({
        //该对象需要包含一个名为render() 的方法来显示组件
        render: function () {
            //该方法必须返回一个React 组件,不能只返回文本内容。
            return React.DOM.span(null, 'I\'m so custom');
        }
    });
    //使用自定义组件
    ReactDOM.render(
        //React.createElement() 是创建组件“实例”的方法之一
        React.createElement(Component),
        //如果你想创建多个实例,还有另一种途径,就是使用工厂方法:React.createFactory(Component);
        document.getElementById('app')
    );
    
    • props和propTypes
    //自定义的组件可以接收属性,所有属性都可以通过this.props对象获取
    var Component = React.createClass({
        //propTypes是可选的,声明组件需要接收的属性列表及其对应类型
        propTypes: {
            //清晰地指明了name 属性是一个必须提供的字符串值
            name: React.PropTypes.string.isRequired,
            middleName: React.PropTypes.string,
        },
        //getDefaultProps() 方法返回一个对象,并为每个可选属性(不带.isRequired的属性)提供了默认值。
        getDefaultProps: function () {
            return {
                middleName: 'chris'
            };
        },
        render: function () {
            //请把this.props 视作只读属性。从父组件传递配置到子组件时,属性非常重要
            return React.DOM.span(null, 'My name is ' + this.props.name);
        }
    });
    ReactDOM.render(
        React.createElement(Component, {
            name: 'Bob'
        }),
        document.getElementById('app')
    );
    
    • 带状态的文本框组件
    var TextAreaCounter = React.createClass({
        propTypes: {
            text: React.PropTypes.string,
        },
        getDefaultProps: function () {
            return {
                text: '',
            };
        },
        // 无状态版本
        render: function () {
            return React.DOM.div(null,
                //文本框使用了defaultValue 属性,而不是你在常规HTML 中习惯使用的文本子元素
                React.DOM.textarea({
                    defaultValue: this.props.text,
                }),
                React.DOM.h3(null, this.props.text.length)
            );
        },
    
        // 有状态版本(状态state负责组件内部数据的维护)
        _textChange: function (ev) {//数据发生改变时(即用户在文本框中输入内容时),组件可以通过一个事件监听器更新state
            this.setState({//改变state 必须使用this.setState() 方法。该方法接收一个对象参数,并把对象与this.state 中已存在的数据进行合并
                text: ev.target.value,
            });
        },
        getInitialState: function () {//在初始化时,定义state中需要包含的属性,以保证可以通过this.state.text访问属性
            return {
                text: this.props.text,
            };
        },
        render: function () {
            return React.DOM.div(null,
                //文本框使用了defaultValue 属性,而不是你在常规HTML 中习惯使用的文本子元素
                React.DOM.textarea({
                    value: this.state.text,
                    //React 使用了合成事件来消除浏览器之间的不一致情况,React 在事件处理中使用驼峰法命名。
                    //当用户输入时触发。而不是像原生DOM 事件那样,在用户结束输入并把焦点从输入框移走时才触发。
                    onChange: this._textChange,
                }),
                React.DOM.h3(null, this.state.text.length)
            );
        }
    });
    // 使用自定义组件
    ReactDOM.render(
        React.createElement(TextAreaCounter, {
            text: "Bob",
        }),
        document.getElementById("app")
    );
    
    • 从外部访问组件(谨慎使用)
    var myTextAreaCounter = ReactDOM.render(
        React.createElement(TextAreaCounter, {
            defaultValue: "Bob",
        }),
        document.getElementById("app")
    );
    //设置了新的state 值
    myTextAreaCounter.setState({ text: "Hello outside world!" });
    //获取了React 创建的父元素DOM 节点的引用
    var reactAppNode = ReactDOM.findDOMNode(myTextAreaCounter);
    //获取DOM 结构中首个<div id="app"> 节点。这也是你让React 进行渲染的位置:
    reactAppNode.parentNode === document.getElementById('app'); // true
    //访问组件的属性和状态
    myTextAreaCounter.props; // Object { defaultValue: "Bob"}
    myTextAreaCounter.state; // Object { text: "Hello outside world!"}
    
    • 中途改变属性
    //这个方法会接收新属性对象,让你可以根据新属性设置state
    componentWillReceiveProps: function(newProps) {
        this.setState({
            text: newProps.defaultValue,
        });
    };
    

    生命周期方法

    初始化

    1. getDefaultProps()

    设置默认的props,也可以用dufaultProps设置组件的默认属性.
    对于组件类来说只调用一次,该组件类的所有后续应用,getDefaultPops 将不会再被调用

    1. getInitialState()

    在使用es6的class语法时是没有这个钩子函数的,可以直接在constructor中定义this.state

    对于组件的每个实例来说,这个方法的调用有且只有一次,用来初始化每个实例的 state,在这个方法里,可以访问组件的 this.props

    getInitialStategetDefaultPops 的调用是有区别的,getDefaultPops 是对于组件类来说只调用一次,后续该类的应用都不会被调用,
    getInitialState 是对于每个组件实例来讲都会调用,并且只调一次。

    1. componentWillMount()

    组件初始化之后,首次渲染之前调用,以后组件更新不调用,整个生命周期只调用一次,是在render 方法调用之前修改 state 的最后一次机会。

    1. render()

    react最重要的步骤,创建虚拟dom,进行diff算法,更新dom树都在此进行。此时就不能更改state了。
    该方法会创建一个虚拟DOM,用来表示组件的输出。对于一个组件来讲,render方法是唯一一个必需的方法。

    render方法需要满足下面几点:

    (1)只能通过 this.propsthis.state 访问数据(不能修改)

    (2)可以返回 null,false 或者任何React组件

    (3)只能出现一个顶级组件,不能返回一组元素

    (4)不能改变组件的状态

    (5)不能修改DOM的输出

    render方法返回的结果并不是真正的DOM元素,而是一个虚拟的表现,类似于一个DOM tree的结构的对象。react之所以效率高,就是这个原因。

    1. componentDidMount()

    组件渲染之后调用,只调用一次。
    该方法被调用时,已经渲染出真实的 DOM,可以再该方法中通过 this.getDOMNode() 访问到真实的 DOM(推荐使用 ReactDOM.findDOMNode())。

    由于组件并不是真实的 DOM 节点,而是存在于内存之中的一种数据结构,叫做虚拟 DOM (virtual DOM)。只有当它插入文档以后,才会变成真实的 DOM 。有时需要从组件获取真实 DOM 的节点,这时就要用到 ref 属性:

    
    var Area = React.createClass({
        render: function () {
            this.getDOMNode(); //render调用时,组件未挂载,这里将报错
    
            return <canvas ref='mainCanvas' >
        },
        componentDidMount: function () {
            var canvas = this.refs.mainCanvas.getDOMNode();
            //这是有效的,可以访问到 Canvas 节点
        }
    });
    

    需要注意的是,由于 this.refs.[refName]属性获取的是真实 DOM ,所以必须等到虚拟 DOM 插入文档以后,才能使用这个属性,否则会报错。

    更新

    此时组件已经渲染好并且用户可以与它进行交互,比如鼠标点击,手指点按,或者其它的一些事件,导致应用状态的改变,你将会看到下面的方法依次被调用

    1. componentWillReceiveProps(nextProps)

    组件的 props 属性可以通过父组件来更改,这时,componentWillReceiveProps 将来被调用。可以在这个方法里更新 state,以触发 render 方法重新渲染组件。

    componentWillReceiveProps: function(nextProps) {
        if (nextProps.checked !== undefined) {
            this.setState({
                checked: nextProps.checked
            })
        }
    }
    
    1. shouldComponentUpdate(nextProps, nextState)

    react性能优化非常重要的一环。
    组件接受新的state或者props时调用,我们可以在此对比前后两个propsstate是否相同。
    如果相同,则返回false阻止更新,因为相同的属性状态一定会生成相同的dom树,这样就不需要创造新的dom树和旧的dom树进行diff算法对比,节省大量性能

    如果你确定组件的 props 或者state 的改变不需要重新渲染,可以通过在这个方法里通过返回 false 来阻止组件的重新渲染,返回 false 则不会执行 render 以及后面的 componentWillUpdatecomponentDidUpdate 方法。

    返回一个布尔值。在组件接收到新的props或者state时被调用。在初始化时或者使用forceUpdate时不被调用。 可以在你确认不需要更新组件时使用。

    该方法是非必须的,并且大多数情况下不会使用。

    1. componentWillUpdate(nextProps, nextState)

    这个方法和 componentWillMount 类似,在组件接收到了新的 props 或者 state 即将进行重新渲染前,componentWillUpdate(object nextProps, object nextState) 会被调用。
    注意此时可以修改state,但最好不要在此方面里再去更新 props 或者 state

    1. render()

    组件渲染

    1. componentDidUpdate()

    这个方法和 componentDidMount 类似,在组件重新被渲染之后,componentDidUpdate(object prevProps, object prevState) 会被调用。可以在这里访问并修改 DOM

    卸载

    1. componentWillUnmount()

    组件将要卸载时调用,一些事件监听和定时器需要在此时清除。

    // 组件卸载
    React.unmountComponentAtNode(this.props.containerNode[0]);
    

    相关文章

      网友评论

          本文标题:React个人整理

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