文章目录

  • 一、React数据流
  • 二、组件的特性
    • 1、属性(props)
      • (1)React Props默认值与标签属性限制
      • (2)应用-React组件切分与提取
    • 2、状态(state)
      • (1)state的定义
      • (2)更新状态
    • 3、refs
      • (1)refs是什么
      • (2)使用方法
        • ①方法一:creactRef(版本>=React16.3)
        • ②方法二:回调Refs
      • (3)refs的作用
    • 4、生命周期
      • (1)挂载(mount)
        • 举例
      • (2)数据更新过程
      • (3)卸载(unmount)
      • (4)总结
        • 命令式编程
        • 声明式编程
        • 生命周期流程
        • 重要的勾子
      • (5)举例

一、React数据流

在 React 中,数据是自顶向下单向流动的,即从父组件到子组件。
      stateprops 是 React 组件中最重要的概念。如果顶层组件初始化 props,那么React 会向下遍历整棵组件树,重新尝试渲染所有相关的子组件。而 state 只关心每个组件自己内部的状态,这些状态只能在组件内改变。把组件看成一个函数,那么它接受了 props 作为参数,内部由 state 作为函数的内部参数,返回一个 Virtual DOM 的实现。

二、组件的特性

1、属性(props)

props是 properties 的缩写,props 是 React 用来让组件之间互相联系的一种机制,通俗地说就像方法的参数一样。
      React 的单向数据流,主要的流动管道就是 props。props 本身是不可变的。当我们试图改变 props 的原始值时,React 会报出类型错误的警告,组件的 props 一定来自于默认属性或通过父组件传递而来。如果说要渲染一个对 props 加工后的值,最简单的方法就是使用局部变量或直接在 JSX 中计算结果。
      在使用函数组件时无论是否传递参数,props属性都是默认存在的。
举例1:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Props属性</title><script src="../js/react.development.js"></script><script src="../js/react-dom.development.js"></script><script src="../js/babel.min.js"></script>
</head>
<body><div id="root"></div><script type="text/babel">let root = document.getElementById('root');//1.定义函数组件function PropsComponent(props){if(props){return (<div><p>Props数据是:</p>&nbsp;&nbsp;&nbsp;<p>姓名:{ props.name }</p><p>年龄:{ props.age }</p></div>)}else{return <p>Props数据为空!</p>}}const span = (<span><PropsComponent name='乔峰' age='28'/><hr /><PropsComponent /></span>)//2.渲染ReactDOM.render(span,root)</script>
</body>
</html>


举例2:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Props属性设置表单的默认值</title><script src="../js/react.development.js"></script><script src="../js/react-dom.development.js"></script><script src="../js/babel.min.js"></script>
</head>
<body><div id="root"></div><script type="text/babel">let root = document.getElementById('root')//1.定义函数组件function UserName(props){const userName = (<p>用户名:<input type="text"  value={ props.uname }/></p>)return userName;}function UserPwd(props){const userPwd = (<p>密&nbsp;&nbsp;&nbsp;码:<input type="password" /></p>)return userPwd;}function FormLogin(){return (<div><h3>用户登录</h3><UserName uname="小红"/><UserPwd /></div>)}//2.渲染ReactDOM.render(<FormLogin/>,root)</script>
</body>
</html>

(1)React Props默认值与标签属性限制

①可以通过Props对虚拟DOM中的标签属性进行类型、必要性的限制
A、导入prop-types.js库文件:对props属性进行类型、必要性的检查
B、通过PropTypes对标签属性进行限制
C、在函数组件中进行类型检查

函数名.propTypes = {属性名:PropTypes.类型名.必要性限制
}

D、在中进行类型检查

//在类的内部使用static进行定义
static propTypes = {属性名:PropTypes.类型名.必要性限制
}
//在类的外部进行定义
类名.propTypes = {属性名:PropTypes.类型名.必要性限制
}

②在函数组件中使用props属性的defaultProps来设置组件的默认值

函数名. defaultProps = {属性名: 默认值
}

举例如下:

...
<body><div id="root"></div><script type="text/babel">let root = document.getElementById('root');//1.定义函数组件function Person(props){const { name,age,sex } = props;return (<ul><li>姓名:{ name }</li><li>年龄:{ age }</li><li>性别:{ sex }</li></ul>)}//2.定义函数组件的默认值Person.defaultProps = {name: '张飞',age: '26',sex: '男'}Person.propTypes = {name: PropTypes.string.isRequired,age: PropTypes.number,sex: PropTypes.string}//3.渲染ReactDOM.render(<Person name="AAAAA"/>,root)</script>
</body>
...

③在类组件中可以使用props属性的defaultProps来设置组件的默认值,标签可以设置defaultValue属性,该属性的值可以是Props属性的值。

类名.defaultProps = {属性名: 默认值
}

举例如下:

<body><div id="root"></div><script type="text/babel">let root = document.getElementById('root');//1.定义类组件class PropsTest extends React.Component{render(){const { name,age,address } = this.props //解构赋值return (<div><label>用户名:<input type="text" defaultValue={ name }/></label><br /><label>年龄:<input type="text" defaultValue={ age }/></label><br /><label>地址:<input type="text" defaultValue={ address }/></label></div>)}}//2.定义类组件的默认值PropsTest.defaultProps = {name : '刘备',age: 28,address: '成都'}//3.渲染ReactDOM.render(<PropsTest />,root)</script>
</body>

//使用static来定义默认值
static.defaultProps = {属性名: 默认值
}

举例如下:

...<body><div id="root"></div><script type="text/babel">let root = document.getElementById('root');//1.定义类组件class PropsTest extends React.Component{//定义默认值static defaultProps = {name : '关羽',age: 28,address: '成都'}//对标签属性值进行限制static propTypes = {name:PropTypes.string.isRequired, //表示name属性值必须是string类型,并且不能缺少age:PropTypes.number,address:PropTypes.string //进行类型限制}render(){const { name,age,address } = this.props //解构赋值return (<div><label>用户名:<input type="text" defaultValue={ name }/></label><br /><label>年龄:<input type="text" defaultValue={ age }/></label><br /><label>地址:<input type="text" defaultValue={ address }/></label></div>)}}//3.渲染ReactDOM.render(<PropsTest />,root)</script></body>...

(2)应用-React组件切分与提取

对React组件进行切分并提取逻辑清晰、可高度复用的小组件,有利于代码的修改和维护

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>组件的切分和提取</title><script src="../js/react.development.js"></script><script src="../js/react-dom.development.js"></script><script src="../js/prop-types.js"></script><script src="../js/babel.min.js"></script>
</head>
<style>body{text-align: center;}div#root{position: relative;width: 500px;height: auto;border: 1px solid gray;margin: 8px auto;padding: 8px;text-align: center;}div.cssUserDetail{width: 480px;height: 320px;padding: 4px;border: 1px solid gray;}span.cssAvator{float: left;width: 32%;height: auto;}span.cssUserInfo{float: right;width: 50%;height: auto;}span.cssDate{float: right;width: 80%;height: auto;}p.p-center{text-align: center;}p.p-left{text-align: left;}p.p-right{text-align: right;}
</style>
<body><div id="root"></div><script type="text/babel">let root = document.getElementById('root');//1.定义日期格式化函数function formatDate(date){return date.toLocaleDateString();}//2.定义常量为组件提供数据const avator = {url: '../images/me.png',alt: 'load...',nikeName:'曹阿瞒'}const userInfo = {id: '007',name: '邦德',gender: '男',age: 29,email: 'king@qq.com'}const nowDate = {date : formatDate(new Date())}//3、定义组件function Avator(props){return (<span className='cssAvator'><img className = 'cssAvatorImg'src={ props.avator.url } alt={ props.avator.alt }/><p className='p-center'>绰号:{ props.avator.nikeName }</p></span>)}function UserInfo(props){return (<span className='cssUserInfo'><p className='p-left'>Id: { props.userInfo.id }</p><p className='p-left'>Name: { props.userInfo.name }</p><p className='p-left'>Gender: { props.userInfo.gender }</p><p className='p-left'>Age: { props.userInfo.age }</p><p className='p-left'>Email: { props.userInfo.email }</p></span>)}function UserDetail(props){ //将Avator、UserInfo组件组合到一起return (<div className='cssUserDetail'><Avator avator = { props.avator }/><UserInfo userInfo = { props.userInfo}/><span className = 'cssDate'><p className='p-right'>Date:{ props.currDate.date }</p></span></div>)}//4.渲染const ComDemo = <UserDetailavator = { avator } userInfo = { userInfo }currDate = { nowDate  }/>ReactDOM.render(ComDemo,root)</script>
</body>
</html>

2、状态(state)

在 React 没有结合 Flux 或 Redux 框架前,它自身也同样可以管理组件的内部状态。在 React 中,把这类状态统一称为state。
      React将组件看成是一个状态机(State Machines) , 通过其内部定义的状态(State) 与生命周期(Lifecycle) 实现与用户的交互, 维持组件不同的状态。
      在React框架中定义了一个状态(State) 概念, 并通过状态(State) 来实现React组件的状态机特性。所谓React组件的“状态机”特性, 就是指组件通过与用户的交互, 实现不同的状态,然后通过渲染UI保证用户界面和数据一致性。React框架之所以定义这个状态(State) 概念, 其目的就是仅仅通过更新React组件的状态(State) , 就可以实现重新渲染用户界面的操作(这样就不需要操作DOM了) 。这点也正React设计理念相较于其他前端框架的先进之处。React State的使用方法相比于Props较为复杂一些, 但也是有基本模式的。 State是完全受控于组件的,所定义的属性值可以根据需求而改变,并在虚拟DOM上同步更新。

(1)state的定义

this.state = {属性名:值
}

(2)更新状态

不能直接给状态机中的属性赋值,必须通过setState方法来更新状态机中的属性值。
      当组件内部使用库内置的 setState 方法时,最大的表现行为就是该组件会尝试重新渲染。因为我们改变了内部状态,组件需要更新了。setState 是一个异步方法,一个生命周期内所有的 setState 方法会合并操作。

this.setState({属性名:新的属性值
})

3、refs

(1)refs是什么

Refs在计算机中称为弹性文件系统(Resilient File System);
      React中的Refs提供了一种方法,允许我们访问DOM节点或者在render方法中创建的React元素(虚拟的DOM元素)。
      本质为ReactDOM.render()返回的组件实例,如果是渲染组件则返回的是组件实例,如果渲染dom则返回的是具体的dom节点

(2)使用方法

①方法一:creactRef(版本>=React16.3)

一般在构造函数中将refs分配给实例属性,以供组件的其他方法使用。
对html元素:可以获取元素实例

import React, { Component } from "react";class RefsComponent extends Component{constructor(props) {super(props);this.myref = React.createRef(); //在构造函数中初始化一个ref,可以关联render中DOM元素,在return中就可以使用了console.log(this.myref)}componentDidMount() {this.myref.current.innerHTML = '哈哈'//this.myRef有一个current属性}handleClick(){ //普通的成员函数,没有绑定thisthis.myref.current.innerHTML = "西安邮电大学"}render(){return (<div><div ref={ this.myref } ></div> {/* 将div与this.myref进行关联,对this.myref的操作实际就是操作div*/}<br/><br/><button onClick={ this.handleClick.bind(this) }>点击修改DIV的内容</button></div>)}
}
export default RefsComponent;


对于类组件:可以获取组件类的实例
子组件:

import React,{ Component } from "react";class Children extends Component{bianshen(){alert('大变身')}render(){return <span>大变身</span>}
}export default Children;

父组件:

import React, {Component, createRef} from "react";
import Children from "./Children";class Parent extends Component{constructor(props) {super(props);this.myref = createRef()}handleClick(){this.myref.current.bianshen()}render() {return (<div><Children ref={ this.myref }/><button onClick={ this.handleClick.bind(this) }>调用子组件的方法</button></div>)}
}
export default Parent;


注意:无法获取函数组件。

②方法二:回调Refs

React将在组件挂载时,调用ref回调函数并传入DOM元素,当卸载时调用它并传入null。在componentDidMount或componentDidUpdate触发前,React会保证refs一定是最新的。

class Example extends React.Component{constructor(props) {super(props);this.targetRef = null;this.myRef = (e)=> this.targetRef = e}componentDidMount() {if(this.targetRef){this.targetRef.innerHTML = 'haha'}}render(){return <div ref = { this.myRef }></div>}
}

附:模块化管理
(1)CommonJS的模块管理:node使用该方式进行模块管理
module.exports = 模块名
(2)React进行模块管理:每个模块都有一个唯一的默认名称(组件名)
exports default 模块名

(3)refs的作用

Refs是React提供给我们的安全访问DOM元素或者某个组件实例的句柄。在类组件中,React将ref属性中第一个参数作为DOM中的句柄。而函数组件中,react用hooks的api useRef也能获得ref。

4、生命周期

生命周期(life cycle)的概念广泛运用于各行各业。从广义上来说,生命周期泛指自然界和人类社会中各种客观事物的阶段性变化及其规律。自然界的生命周期,可分为出生、成长、成熟、衰退直到死亡。而不同体系下的生命周期又都可以从上述规律中演化出来,运用到软件开发的生命周期上,这二者看似相似,事实上又有所不同。生命体的周期是单一方向不可逆的过程,而软件开发的生命周期会根据方法的不同,在完成前重新开始。
      每个组件都包含 “生命周期方法”,可以重写这些方法,以便于在运行过程中特定的阶段执行这些方法。
      React 组件的生命周期根据广义定义描述,可以分为挂载渲染卸载这几个阶段。当渲染后的组件需要更新时,我们会重新去渲染组件,直至卸载。
      因此,我们可以把 React 生命周期分成两类:

当组件在挂载或卸载时;
当组件接收新的数据时,即组件更新时。

装载(挂载)过程(mount):就是组件第一次在DOM树中渲染的过程
更新过程(update):组件被重新渲染的过程
卸载过程(unmount):组件从DOM中被移除的过程

(1)挂载(mount)

组件挂载是最基本的过程,这个过程主要做组件状态的初始化,当组件实例被创建并插入 DOM 中时,其生命周期调用顺序如下:

import React, { Component, PropTypes } from 'react';
class App extends Component { static propTypes = { // ... }; static defaultProps = { // ... }; constructor(props) { super(props); this.state = { // ... }; } componentWillMount() { // ... }render() { return <div>This is a demo.</div>; } componentDidMount() { // ... }
}

propTypes:props 类型检查
defaultProps:props默认类型

这两个属性被声明成静态属性,意味着从类外面也可以访问它们,比如可以这么访问:App.propTypes和 App.defaultProps。

constructor(props) :构造方法

如果不初始化 state 或不进行方法绑定,则不需要为 React 组件实现构造函数。在 React 组件挂载之前,会调用它的构造函数。在为 React.Component 子类实现构造函数时,应在其他语句之前调用 super(props)。否则,this.props 在构造函数中可能会出现未定义的 bug。
      通常,在 React 中,构造函数仅用于以下两种情况:
通过给 this.state 赋值对象来初始化内部 state为事件处理函数绑定实例
      在 constructor() 函数中不要调用 setState() 方法。如果你的组件需要使用内部 state,请直接在构造函数中为 this.state 赋值初始化state:

    constructor(props){super(props);//不要在这里调用this.setStatethis.state = {//属性:属性值};this.handleClick = this.handleClick.bind(this);}

componentWillMount:在 render 方法之前执行
componentDidMount:在 render 方法之后执行

它们分别代表了渲染前后的时刻,这个初始化过程没什么特别的,包括读取初始 state 和 props 以及两个组件生命周期方法componentWillMount 和 componentDidMount,这些都只会在组件初始化时运行一次。
      componentDidMount会在组件挂载后(插入 DOM 树中)立即调用。依赖于 DOM 节点的初始化应该放在这里。如需通过网络请求获取数据,此处是实例化请求的好地方。 这个方法是比较适合添加订阅的地方。如果添加了订阅,请不要忘记在 componentWillUnmount() 里取消订阅。
      可以在 componentDidMount() 里直接调用 setState()。它将触发额外渲染,但此渲染会发生在浏览器更新屏幕之前。如此保证了即使在 render() 两次调用的情况下,用户也不会看到中间状态。请谨慎使用该模式,因为它会导致性能问题。通常,你应该在 constructor() 中初始化 state。如果你的渲染依赖于 DOM 节点的大小或位置,比如实现 modals 和 tooltips 等情况下,你可以使用此方式处理

render()

是 class 组件中唯一必须实现的方法 ,当 render 被调用时,它会检查 this.props 和 this.state 的变化并返回以下类型之一:
React 元素,通常通过 JSX 创建。例如,< div / > 会被 React 渲染为 DOM 节点,< MyComponent /> 会被 React 渲染为自定义组件,无论是 < div /> 还是 < MyComponent /> 均为 React 元素。
数组或 fragments,使得 render 方法可以返回多个元素。
Portals,可以渲染子节点到不同的 DOM 子树中。
字符串或数值类型。它们在 DOM 中会被渲染为文本节点。
布尔类型或 null。什么都不渲染。(主要用于支持返回 test && < Child /> 的模式,其中 test 为布尔类型。)
      render() 函数应该为纯函数,它并不进行实际上的渲染动作,它只是一个JSX描述的结构,最终是由React来进行渲染过程,render函数中不应该有任何操作,对页面的描述完全取决于this.state和this.props的返回结果,不能在render调用this.setState。这意味着在不修改组件 state 的情况下,每次调用时都返回相同的结果,并且它不会直接与浏览器交互。如需与浏览器进行交互,要在 componentDidMount() 或其他生命周期方法中执行操作。保持 render() 为纯函数,可以使组件更容易使用、维护。

举例

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>组件的生命周期</title><script src="../js/react.development.js"></script><script src="../js/react-dom.development.js"></script><script src="../js/babel.min.js"></script>
</head>
<body><div id="root"></div><script type="text/babel">let root = document.getElementById('root');//1.定义类组件class Clock extends React.Component{constructor(props){super(props)//定义状态机并初始化this.state = {date: new Date(),show: true,text: '隐藏'}//进行事件绑定:当某个事件被触发时,调用谁的事件处理函数this.handleClickShow = this.handleClickShow.bind(this); //将事件处理函数绑定到this}componentDidMount(){ //挂载完成后立即执行的函数:即页面打开时就可以看到组件this.timerID = setInterval(()=> this.tick(),1000)}componentWillUnmount(){ //组件卸载后关闭定时器clearInterval(this.timerID)}tick(){ //自定义方法:改变状态机(改变状态机中的属性值)this.setState({date: new Date()})}handleClickShow(){this.setState(state=>({ //参数state表示以前的状态show: !state.show,text: !state.show?'隐藏':'显示'}))}render(){let isShow = this.state.showlet element;if (isShow) {element = <h2>{this.state.date.toLocaleTimeString()}</h2>}else{element = null}return (<div><button onClick={ this.handleClickShow }>{this.state.text}计时器</button><br />{ element }</div>)}}//2.渲染ReactDOM.render(<Clock />,root)</script>
</body>
</html>


(2)数据更新过程

更新过程指的是父组件向下传递 props 或组件自身执行 setState 方法时发生的一系列更新动作。即当组件的props或state发生改变时,就会触发更新操作。这里我们屏蔽了初始化的生命周期方法,以便观察更新过程的生命周期:

import React, { Component, PropTypes } from 'react';
class App extends Component { componentWillReceiveProps(nextProps) { // this.setState({}) } shouldComponentUpdate(nextProps, nextState) { // return true; } componentWillUpdate(nextProps, nextState) { // ... } render() { return <div>This is a demo.</div>; } componentDidUpdate(prevProps, prevState) { // ... }
}

如果组件自身的 state 更新了,那么会依次执行componentWillReceiveProps、shouldComponentUpdate、componentWillUpdate 、render 和 componentDidUpdate。

componentWillReceiveProps(nextProps)

并不是只有在props发生改变的时候才会被调用,实际上只要是父组件的render函数被调用,render里面被渲染的子组件就会被更新,不管父组件传给子组件的props有没有被改变,都会触发子组件的componentWillReceiveProps过程,但是,this.setState方法的触发过程不会调用这个函数,因为这个函数适合根据新的props的值来计算出是不是要更新内部状态的state。

shouldComponentUpdate()

shouldComponentUpdate 是一个特别的方法,它接收需要更新的 props 和 state,让开发者增加必要的条件判断,让其在需要时更新,不需要时不更新。因此,当方法返回 false 的时候,组件不再向下执行生命周期方法。shouldComponentUpdate 的本质是用来进行正确的组件渲染。

componentWillUpdate (nextProps, nextState)
componentDidUpdate(prevProps, prevState, snapshot)

componentWillUpdatecomponentDidUpdate这两个生命周期方法很容易理解,对应的初始化方法也很容易知道,它们代表在更新过程中渲染前后的时刻。此时,我们可以想到 componentWillUpdate 方法提供需要更新的 props 和 state,而 componentDidUpdate 提供更新前的 props 和state。

componentDidUpdate(prevProps){//不要忘记propsif(this.props.uresID !== prevProps.uresID){this.fetchDate(this.props.uresID)}
}

也可以在 componentDidUpdate() 在组件更新后立即调用,它可以直接调用 setState(),但请注意它必须被包裹在一个条件语句里,正如上述的例子那样进行处理,否则会导致死循环。它还会导致额外的重新渲染,虽然用户不可见,但会影响组件性能。

如果组件是由父组件更新 props 而更新的,那么在 shouldComponentUpdate 之前会先执行componentWillReceiveProps 方法。此方法可以作为 React 在 props 传入后,渲染之前setState 的机会。在此方法中调用 setState 是不会二次渲染的。

(3)卸载(unmount)

组件卸载非常简单,只有 componentWillUnmount 这一个卸载前状态,当组件从 DOM 中移除时会调用该方法。在componentWillUnmount 方法中,我们常常会执行一些清理方法,如事件回收或是清除定时器。

componentWillUnmount

会在组件卸载及销毁之前直接调用。在此方法中执行必要的清理操作,例如,清除timer,取消网络请求或清除在 componentDidMount() 中创建的订阅等。componentWillUnmount() 中不应调用 setState(),因为该组件将永远不会重新渲染。组件实例卸载后,将永远不会再挂载它。

注意:在react中,触发render的有4条路径:
以下假设shouldComponentUpdate都是按照默认返回true的方式。

(1)首次渲染Initial Render
(2)调用this.setState(并不是一次setState会触发一次render,React可能会合并操作,再一次性进行render)
(3)父组件发生更新(一般就是props发生改变,但是就算props没有改变或者父子组件之间没有数据交换也会触发render)
(4)调用this.forceUpdate

注意:如果在shouldComponentUpdate里面返回false可以提前退出更新路径。

(4)总结

命令式编程

jquery(自己寻找要操作的DOM元素,自己写要做的事情)

声明式编程

react(只需要在钩子函数中写东西即可,不需要执行钩子函数)这些钩子函数是本身就会执行的,我们重写了一部分,是为了在这个组件的某个时期做一些事情。

生命周期流程

1、第一次初始化渲染显示: ReactDOM.render()

constructor(): 创建对象初始化 state
componentWillMount() : 将要插入回调
render() : 用于插入虚拟 DOM 回调
componentDidMount() : 已经插入回调

2、每次更新 state: this.setState()

componentWillUpdate() : 将要更新回调
render() : 更新(重新渲染)
componentDidUpdate() : 已经更新回调

3、移除组件: ReactDOM.unmountComponentAtNode(containerDom)

componentWillUnmount() : 组件将要被移除回调

重要的勾子

1、render(): 初始化渲染或更新渲染调用
2、componentDidMount(): 开启监听, 发送 ajax 请求
3、componentWillUnmount(): 做一些收尾工作, 如: 清理定时器

(5)举例

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>生命周期函数</title><script src="../js/react.development.js"></script><script src="../js/react-dom.development.js"></script><script src="../js/babel.min.js"></script>
</head>
<body><div id="root"></div><script type="text/babel">let root = document.getElementById('root')class LifeCycle extends React.Component {constructor(props){super(props);alert("Initial render");alert("constructor");this.state={str: "hello"};this.setTheState = this.setTheState.bind(this)}componentWillMount(){alert("componentWillMount");}componentDidMount(){alert("componentDidMount");}shouldComponentUpdate(){alert("shouldComponentUpdate");return true;// 记得要返回true}componentWillUpdate(){alert("componentWillUpdate");}componentDidUpdate(){alert("componentDidUpdate");}componentWillUnmount(){alert("componentWillUnmount");}setTheState(){let s = "hello";if(this.state.str === s){s = "HELLO";}this.setState({str: s});}render(){alert("render");return(<div><span>"State:" {this.state.str}</span><br /> <br /><button onClick={ this.setTheState }>更新</button></div>);}}ReactDOM.render(<LifeCycle />,root)</script>
</body>
</html>

React学习二(组件详解)相关推荐

  1. React Native-9.React Native Touchable组件详解

    Touchable系列组件简介 RN中没有web中给元素绑定click事件的机制,但是在上一节中我们知道Text组件中我们可以绑定onPress事件来触发点击事件,为了像Text组件那样使得其它组件可 ...

  2. react高阶组件详解

    1 引言 高阶组件( higher-order component ,HOC )是 React 中复用组件逻辑的一种进阶技巧.它本身并不是 React 的 API,而是一种 React 组件的设计理念 ...

  3. react 高阶组件详解

    1.高阶组件是什么 高阶组件是一个函数,但 参数 和 返回值 为 组件. 高阶组件是包装了另外一个 React 组件的 React 组件.它可以大幅度的简化代码量.使我们更多的去复用代码: 高阶组件可 ...

  4. 【Unity3D-UGUI系列】(十二)ScrollView 滚动视图组件详解

    推荐阅读 CSDN主页 GitHub开源地址 Unity3D插件分享 简书地址 我的个人博客 QQ群:1040082875 大家好,我是佛系工程师☆恬静的小魔龙☆,不定时更新Unity开发技巧,觉得有 ...

  5. UE4移动组件详解(二)——移动同步机制

    第一部分从移动相关架构以及单机情况下移动的处理细节讲起 UE4移动组件详解(一)--移动框架与实现原理 而第二部分是关于移动组件同步解决方案的描述,里面有诸多细节来让移动的同步表现的更为流畅.关于移动 ...

  6. 深度学习开发环境调查结果公布,你的配置是这样吗?(附新环境配置) By 李泽南2017年6月26日 15:57 本周一(6 月 19 日)机器之心发表文章《我的深度学习开发环境详解:Te

    深度学习开发环境调查结果公布,你的配置是这样吗?(附新环境配置) 机器之心 2017-06-25 12:27 阅读:108 摘要:参与:李泽南.李亚洲本周一(6月19日)机器之心发表文章<我的深 ...

  7. ue4移动到一定距离_UE4移动组件详解(一)——移动框架与实现原理

    原文链接(转载请标明):UE4移动组件详解(一)--移动框架与实现原理_Jerish的博客-CSDN博客​blog.csdn.net 前言 关于UE4的移动组件,我写了一篇非常详细的分析文档.由于篇幅 ...

  8. 跟着小马哥学系列之 Spring AOP(Pointcut 组件详解)

    学好路更宽,钱多少加班. --小马哥 版本修订 2021.5.19:去除目录 2021.5.21:引用 Spring 官方 Pointcut 概念,修改 Pointcut 功能表述 简介 大家好,我是 ...

  9. 【Unity3D-UGUI系列】(一)Canvas 画布组件详解

    推荐阅读 CSDN主页 GitHub开源地址 Unity3D插件分享 简书地址 我的个人博客 QQ群:1040082875   大家好,我是佛系工程师☆恬静的小魔龙☆,不定时更新Unity开发技巧,觉 ...

  10. Vuex入门(二)—— mutations详解

    目录 知识不足的地方赶快点击学习呦~~~ Vuex入门(一)-- state,mapState,-mapState对象展开符详解 Vuex入门(二)-- mutations详解 Vuex入门(三)-- ...

最新文章

  1. 企业如何利用新闻类软文营销策划
  2. 输入20本书的书名,作者,出版社,出版日期,单价,按书名排序输出
  3. matlab 霍特林变换,数字图像处理(第3版面向CS2013计算机专业规划教材)
  4. linux 比较新的设备树 详解 device tree
  5. NumPy之:NumPy简介教程
  6. 【孤儿进程】孤儿进程组、守护进程
  7. [导入]ASP.NET MVC框架开发系列课程(1):MVC模式与ASP.NET MVC框架概述.zip(8.80 MB)
  8. python201811210作业4
  9. 把uliweb项目变成可安装的python包
  10. paip.提升安全性------登录地区变换后进行验证
  11. 【Unity3D读取数据】(三)Xml文件操作(创建、读取、写入、修改)
  12. 通信原理 | 信道的概念和实际信道
  13. 2021鹏业安装算量软件常见问题整理(四)
  14. 防火墙、waf、ips和ddos的部署
  15. 计算机课堂小游戏活跃气氛,活跃气氛的70个小游戏 比较嗨的暖场游戏
  16. Groovy学习(二):GDK初探
  17. win8关闭uefi+linux,UEFI启动是什么意思?Win8关闭UEFI引导方式的方法
  18. c语言 实习报告,计算机专业c语言实训报告范文
  19. 中国智能音箱争夺战,国外巨头缺席BAT各有心思
  20. 帆软FineReport学习篇(二)

热门文章

  1. f-Strings:一种改进Python格式字符串的新方法
  2. secureFX上传中文文件名乱码
  3. 8.dfs--王子救公主(遍历迷宫,王子和公主访问过同一位置,即成功救公主)
  4. 山东大学创新实训---前端原型设计以及环境配置
  5. 代数合并同类项计算机步骤,代数式(合并同类项)
  6. 七大设计原则(一):开闭原则
  7. SqlDBHelper(基础增删改查)
  8. NHWC BGR -> NCHW RGB
  9. 12.1 Prim算法
  10. neutron组网规划(flat、vlan类型)