一、实现组件的方法:
组件名称首字母必须大写
- 通过JS函数方式实现组件
<div id="app"></div>
<script type="text/babel"> var ReactDiv = document.getElementById('app'); function GetReactComp(){ return <p>我是react组件</p> } const hellocomp = < GetReactComp /> //首字母大写 const reactSpan = ( <span> { hellocomp } </span> ) ReactDOM.render(reactSpan,ReactDiv)
</script>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 通过ES6 class实现组件
<div id="class"></div>
<script type="text/babel"> var reactDiv1=document.getElementById('class'); //定义类组件 class MyReactComp extends React.Component{ render(){ return ( <h2>类组件</h2> ) } } //使用类组件 const testDiv = ( <div>{<MyReactComp/>}</div> )
//挂载 ReactDOM.render(testDiv,reactDiv1)
</script>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
二、props组件传值
React对props有严格的保护机制,一旦给定值,在组件中不允许被改变
。
<div id="app"></div>
<script type="text/babel"> var reactDiv = document.getElementById('app'); class ReactClassComp extends React.Component { render(){ return ( <div> <p>用户名:<input type="text" value={ this.props.name }/></p> <p>性别:<input type="text" value={ this.props.gender }/></p> </div> ) } } ReactClassComp.defaultProps={ name:'刘备', gender:'男' } const reactp=( <span> {<ReactClassComp />} </span> ) ReactDOM.render(reactp,reactDiv)
</script>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
注意: 在很多场合中,组件的内容需要根据数据的刷新而刷新,这个时候就需要用到React提供的State
三、State状态
-
React将组件看作是
状态机
,通过内部定义的状态与生命周期实现与用户的交互,维持组建的不同状态,然后通过渲染UI保证用户界面和数据一致性。 -
创建方式:利用ES6的class继承方法
super
,可以将props传递到React.Component的构造函数中。
1.React生命周期
挂载(mount):
当组件实例被创建并插入DOM中时
(1)constructor(props)
-->在组件挂载之前,会调用它的构造函数。如果不需要初始化state或不进行方法绑定,则不需要创建构造函数。
构造函数仅用于以下两种情况:
- 通过给this.state赋值对象来初始化内部state
- 为事件处理函数绑定实例
注意: 在constructor()函数中不要调用setState()方法。如果需要使用内部state,可直接在构造函数中为this.state赋值初始化state.
constructor(props){
super(props);
this.state = { date:new Date()
}
this.handleShow = this.handleShow.bind(this)
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
(2) render()
-->必须要实现的
会检查this.props和this.state的变化并返回以下类型之一:
- React元素:通常通过JSX创建
- 数组或fragments:返回多个
- Portals:可以渲染节点到不同的DOM子树中
- 字符串或数值类型:被渲染为文本节点
- 布尔类型或null:什么都不渲染
纯函数
:在不修改组件state的情况下,每次调用都返回相同的结果,并且它不会直接与浏览器交互。
如果需与浏览器进行交互,在ComponmentDidMount()或其他生命周期中进行定义
(3) ComponmentDidMount()
-->在组件挂载后立即调用。
- 依赖DOM节点的初始化
- 实例化网络请求获取数据
- 添加订阅,需要在componentWillUnmount()中取消订阅
注意: 可以在ComponmentDidMount()中直接调用setState()。它将触发额外渲染,但此渲染会发生在浏览器更新屏幕之前。保证了即使在render()两次调用的情况下,用户不会看到中间状态。
更新:
compomentDidUpdate(prevProps,prevProps,snapshot)
:更新后立即调用,首次渲染不会执行此方法,当组件更新后,可以在此处对DOM进行操作。
compomentDidUpdate(prevProps){
if(this.props.userID !== prevProps.userID){
this.fetchData(this.props.userID)
}
}
- 1
- 2
- 3
- 4
- 5
注意: 若在compomentDidUpdate() 调用setState(),需要包裹在一个条件语句中,否则会导致死循环。还会导致额外的重新渲染,虽然用户不可见,但会影响组件性能。
卸载:
componentWillUnmount()
-->在组件卸载及销毁之前直接调用。
注意: componentWillUnmount()中不应调用setState()方法,因为组件将永远不会重新渲染。组件实例卸载后,将永远不会再挂载它。
2.生命周期实例-->时钟:
<div id="app"></div>
<script type="text/babel"> var reactDiv = document.getElementById('app') //定义类组件 MyStateComp class MyStateComp extends React.Component { //构造函数 constructor(props) { super(props); //通过this.state初始化state内部 this.state = { date:new Date(), show:false, text:'显示' } //为事件处理函数绑定实例 this.handleShow = this.handleShow.bind(this) } //添加订阅 componentDidMount() { this.timerID = setInterval(()=>this.tick(),1000) } //时间函数 tick() { this.setState({ //setState更新组件的state date:new Date() }) } //实例显示、隐藏 handleShow() { this.setState(state=>({ show: !state.show, text: !state.show?'隐藏':'显示' })) } //组件卸载:清空定时器 componentWillUnmont() { clearInterval(this.timerID) } render() { let isShow=this.state.show; let element; if(isShow){ element = <h2 >{this.state.date.toLocaleTimeString()}</h2> }else{ element = null } return ( <div> <button onClick={this.handleShow}>{this.state.text}时间</button> {element} </div> ) } } const reactSpan = ( <span> {<MyStateComp/> } </span> ) ReactDOM.render(reactSpan,reactDiv)
</script>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
文章来源: blog.csdn.net,作者:一枚小棋子,版权归原作者所有,如需转载,请联系作者。
原文链接:blog.csdn.net/isfor_you/article/details/115026703