美文网首页
组件&生命周期

组件&生命周期

作者: 奶瓶SAMA | 来源:发表于2018-06-04 16:07 被阅读0次

组件使你可以将 UI 划分为一个一个独立,可复用的小部件,并可以对每个部件进行单独的设计。

从定义上来说, 组件就像JavaScript的函数。封装内容, 达到重用的目的.
组件可以接收任意输入(称为”props”), 并返回 React 元素,用以描述屏幕显示内容

两种组件创建的方式
1.函数式组件

<!DOCTYPE html>
<html>

    <head>
        <meta charset="UTF-8" />
        <title>Hello World</title>
        <!--react的核心库-->
        <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>

        <!--react的与dom相关的一些功能-->
        <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

        <!--将浏览器不支持的jsx语法转化为js语法-->
        <script crossorigin src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
    </head>

    <body>
        <div id="root"></div>
        
        
    </body>

</html>
<!--
    
    组件:组成的部件,可以接受任何props输入,并返回元素
    
-->
<script type="text/babel">

    // 1. 创建一个基本的组件
    function Welcome(){
        return (
            <div>
                <p>哈哈</p>
            </div>
        )
    }

    // 2. 组件的使用
    ReactDOM.render(
        <Welcome></Welcome>, 
        document.getElementById('root') 
    );

</script>

类组件

<!DOCTYPE html>
    <html>
    
        <head>
            <meta charset="UTF-8" />
            <title>Hello World</title>
            <!--react的核心库-->
            <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
    
            <!--react的与dom相关的一些功能-->
            <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
    
            <!--将浏览器不支持的jsx语法转化为js语法-->
            <script crossorigin src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
        </head>
    
        <body>
            <div id="root"></div>
            
            
        </body>
    
    </html>
    <!--
        
        组件:组成的部件,可以接受任何props输入,并返回元素
        
    -->
    <script type="text/babel">
    
        // 1. 创建一个基本的组件
        class Welcome extends React.Component{
            render (){
                return (
                    <div>
                        <p>哈哈</p>
                    </div>
                )
            }
        }
    
        // 2. 组件的使用
        ReactDOM.render(
            <Welcome></Welcome>, 
            document.getElementById('root') 
        );
    
</script>

生命周期

state和生命周期

state 允许 React 组件在不违反props规则的情况下, 根据用户操作, 网络响应, 或者其他随便什么东西, 来动态地改变其输出。
类似于vue中的data

state的定义

在类组件的constructor中定义state

constructor(props) {
    super(props);
    this.state = {
      posts: [],
      comments: []
    };
  }

****不能直接修改state(需要调用this.setState())

// 错误  这样将不会重新渲染一个组件:
this.state.comment = 'Hello';
// 正确    用 setState() 代替:
this.setState({comment: 'Hello'});
唯一可以分配 this.state 的地方是构造函数。

state(状态) 更新可能是异步的

使用回调函数的形式实现异步操作

需要将对象参数转变为回调函数的形式

// 错误
this.setState({
  counter: this.state.counter + this.props.increment,
});


// 正确
this.setState((prevState, props) => ({
  counter: prevState.counter + props.increment
}));
使用另一种 setState() 的形式,它接受一个函数而不是一个对象。
这个函数将接收前一个状态作为第一个参数,应用更新时的 props 作为第二个参数:

state(状态)更新会被合并
你的状态可能包含几个独立的变量:

constructor(props) {
  super(props);
  this.state = {
    posts: [],
    comments: []
  };
}

***调用this.setState()修改单个的状态不会影响其他的状态,只会合并当前修改的这一个状态

钩子函数是window消息处理机制的一部分,通过设置”钩子”,应用程序可以在系统级对所有消息,事件进行过滤,访问在正常情况下无法访问的消息

钩子函数的本质是一段用以处理系统消息的程序,通过系统调用,把它挂入系统

react组件的三个状态
1.mount
2.update
3.unmount
react针对以上三种状态都封装了hook函数

生命周期钩子详解
如下这些方法在组件实例被创建和被插入到dom中时被调用。

1.constructor()

---constructor初始化state的好地方。如果我们不需要初始化state,也不需要bind任何方法,那么在我们的组件中不需要实现constructor函constructor在组件被mounted之前调用,我们的组件继承自React.Component,constructor函数中我们在其他操作前应该先调用super(props),否则this.props将会是undefined。

---constructor初始化state的好地方。如果我们不需要初始化state,也不需要bind任何方法,那么在我们的组件中不需要实现constructor函数。

----注意下面这种情况,很容易产生bug,我们通常的做法是提升state到父组件,而不是使劲的同步state和props。

constructor(props) {
  super(props);
  this.state = {
    color: props.initialColor
  };
}

componentWillMount()

--此方法在mounting之前被立即调用,它在render()之前调用,因此在此方法中setState不会触发重新渲染。此方法是服务器渲染中调用的唯一的生命周期钩子,通常我们建议使用constructor()。
render()
--render()方法是react组件必须的,它检查this.props和this.state并且返回一个React元素,我们也可以返回null或false,代表我们不想有任何的渲染。
--render()方法应该是一个纯方法,即它不会修改组件的state,在每一次调用时返回同样的结果。它不直接和浏览器交互,如果我们想要交互,应该在componentDidMount()或者其他的生命周期函数里面。
componentDidMount()
--此方法在组件被mounted之后立即被调用,初始化dom节点应该在此方法中,如果需要从远端健在数据,这里是实例化网络请求的好地方,此方法中setState会触发组件重新渲染。

Updating

props和state的改变产生更新。在重新渲染组建时,如下的方法被调用
componentWillReceiveProps()

一个已经mounted的组件接收一个新的props之前componentWillReceiveProps()被调用,如果我们需要更新state来响应prop的更改,我们可以在此方法中比较this.props和nextProps并使用this.setState来更改state。

注意,即使props没有改变,React也可以调用这个方法,因此如果你只想处理改变,请确保比较当前值和下一个值。当父组件导致你的组件重新渲染时,可能会发生这种情况。

React在组件mounting期间不会调用此方法,只有在一些组件的props可能被更新的时候才会调用。调用this.setState通常不会触发componentWillReceiveProps。

shouldComponentUpdate()

使用此方法让React知道组件的输出是否不受当前state或props更改的影响。默认行为是在每次state更改时重新渲染组件,在大多数情况下,我们应该默认改行为。

当接收到新的props或state时,shouldComponentUpdate()在渲染之前被调用。默认返回true,对于初始渲染或使用forceUpdate()时,不调用此方法。返回false不会阻止子组件的state更改时,该子组件重新渲染。

如果shouldComponentUpdate()返回false,那么componentWillUpdate(),render()和componentDidUpdate()将不会被调用。在将来,React可能将shouldComponentUpdate()作为提示而不是strict指令,返回仍然可能导致组件重新渲染。

componentWillUpdate()

当接收新的props或state时,componentWillUpdate()在组件渲染之前被立即调用。使用此函数作为在更新发生之前执行准备的机会。初始渲染不会调用此方法。

注意:这里不能调用this.setState()(如果调用会怎么样?好奇心很重呀,试了一下,会产生死循环,一直更新。

如果我们需要更新state以响应props的更改,我们应该使用componentWillReceiveProps()

render()

render()方法是react组件必须的,它检查this.props和this.state并且返回一个React元素,我们也可以返回null或false,代表我们不想有任何的渲染。

render()方法应该是一个纯方法,即它不会修改组件的state,在每一次调用时返回同样的结果。它不直接和浏览器交互,如果我们想要交互,应该在componentDidMount()或者其他的生命周期函数里面。

componentDidUpdate()

此函数在更新后立即被调用。初始渲染不调用此方法。

当组件已经更新时,使用此操作作为DOM操作的机会。这也是一个好的地方做网络请求,只要你比较当前的props和以前的props(例如:如果props没有改变,可能不需要网络请求)。

Unmounting

当从dom中移除组件时,这个方法会被调用

componentWillUnmount()
此函数在组件被卸载和销毁之前被立即调用。在此方法中执行一些必要的清理。例如清除计时器,取消网络请求或者清理在componentDidMount中创建的任何DOM元素。

<!DOCTYPE html>
<html>

    <head>
        <meta charset="UTF-8" />
        <title>Hello World</title>
        <!--react的核心库-->
        <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>

        <!--react的与dom相关的一些功能-->
        <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

        <!--将浏览器不支持的jsx语法转化为js语法-->
        <script crossorigin src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
    </head>

    <body>
        <div id="root"></div>
    </body>

</html>
<script type="text/babel">
    
    // 创建一个类组件
    class LifeCycle extends React.Component {
        
        // 1. mount阶段
        constructor(props) {
            super(props);
            this.state = {name: 'wlt'};
            this.changeState = this.changeState.bind(this);
            console.log('constructor');
        }
        
        componentWillMount() {
            console.log('componentWillMount');
        }
        
        render() {
            console.log('render');
            return (
                <div className="life-cycle-bg">
                    <p>Hello {this.props.value}</p>
                    <p>Hello {this.state.name}</p>
                    <button onClick={this.changeState}>改变lifeCycle的state</button>
                </div>
            );
        }
        
        componentDidMount() {
            console.log('componentDidMount');
        }
        
        // 2. update阶段
        componentWillReceiveProps(nextProps) { // 只作用于属性的变化,不作用于状态的变化
            console.log('componentWillReceiveProps');
        }
    
        shouldComponentUpdate(nextProps, nextState) {
            console.log('shouldComponentUpdate');
            return true;
        }
    
        componentWillUpdate(nextProps, nextState) {
            console.log('componentWillUpdate');
        }
        
        // ---- render会重新执行
    
        componentDidUpdate(prevProps, prevState) {
            console.log('componentDidUpdate');
        }
        
        // 3. Unmount阶段
        componentWillUnmount(prevProps, prevState) {
            console.log('componentWillUnmount');
        }
        
        // 修改状态
        changeState() {
            this.setState({name: 'sxm'});
        }
    }
    
    class ParentLifeCycle extends React.Component {
        constructor(props) {
            super(props);
            this.state = {
                value: 'World',
                destroyed: false,
                rerender: false
            };
            this.handleChange = this.handleChange.bind(this);
            this.destroyComponent = this.destroyComponent.bind(this);
            this.handleRerender = this.handleRerender.bind(this);
        }
    
        handleChange() {
            this.setState((prevState, props) => ({
                value: prevState.value + ' wlt'
            }));
        }
    
        handleRerender() {
            this.setState({rerender: true});
        }
    
        destroyComponent() {
            this.setState({destroyed: true});
        }
    
        render() {
            if(this.state.destroyed) return null;
            return (
                <div className="parent-life-cycle-bg">
                    <p>
                        <button onClick={this.handleChange}>改变LifeCyle的props</button>
                        <button onClick={this.handleRerender}>父组件重新渲染,子组件re-render</button>
                        <button onClick={this.destroyComponent}>删除组件</button>
                    </p>
                    <LifeCycle value={this.state.value}/>
                </div>
            );
        }
    }
    
    ReactDOM.render(
        <ParentLifeCycle />, document.getElementById('root')
    );
</script>

state 和 生命周期

实现一个基本的定时器功能

<!DOCTYPE html>
<html>

    <head>
        <meta charset="UTF-8" />
        <title>Hello World</title>
        <!--react的核心库-->
        <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>

        <!--react的与dom相关的一些功能-->
        <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

        <!--将浏览器不支持的jsx语法转化为js语法-->
        <script crossorigin src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
    </head>

    <body>
        <div id="root"></div>
    </body>

</html>
<script type="text/babel">


    // 创建一个组件 -- 使用函数式组件
    function Clock(){
        // 创建元素
        const element = (
            <div>
                <h1>hello world!</h1>
                <h2>It is {new Date().toLocaleTimeString()}</h2>
            </div>
        )
        
        // 使用render函数渲染已经创建的元素
        ReactDOM.render(
            element, 
            document.getElementById('root') 
        );
    }
    
    setInterval(Clock,1000)


</script>

存在的问题

完成定时器的功能,使用组件化的形式进行封装的时候,在进行组件调用的时候应该能够直接通过 就能完成一个定时器,而不用再配合外部的js操作

这样做的话能够实现相关的功能,但是不利于复用

相关文章

  • 1组件的生命周期

    组件的生命周期:组件从创建到销毁的过程称为组件的生命周期。组件的生命周期通常分为三个阶段: 组件的挂在阶段。 组件...

  • Flutter 生命周期研究与应用

    Flutter 生命周期包括了组件的生命周期以及App的生命周期。 一、组件生命周期 一个flutter组件主要分...

  • 进阶react.js

    组件生命周期 组件的生命周期有助于理解组件的运行方式,完成更复杂的组件功能、分析组件错误原因等组件的生命周期: 组...

  • 二、Lifecycle

    使用生命周期感知组件处理生命周期 生命周期感知组件可以在其他组件(例如 activity 和 fragment)的...

  • React 生命周期

    React 生命周期 初始化周期 组件重新渲染生命周期 组件卸载生命周期

  • React 组件生命周期

    组件生命周期 参考阅读: component-lifecycle react组件生命周期过程说明 react 组件...

  • React概念图

    React概念图 React组件生命周期概念图 参考文档:React入门教程 组件生命周期React:组件生命周期...

  • 2、Android官方架构组件介绍之LifeCycle(一)

    Android官方架构组件介绍之LifeCycle 使用生命周期感知组件处理生命周期 支持生命周期的组件会响应另一...

  • React总结

    [toc] 1.React组件生命周期 1.1 生命周期图 组件的生命周期的图如下: 具体可参考React 组件生...

  • Android Jetpack架构篇:Lifecycles

    Android Jetpack架构篇:Lifecycles 使用生命周期感知组件处理生命周期 生命周期感知组件执行...

网友评论

      本文标题:组件&生命周期

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