269 lines
7.6 KiB
Markdown
269 lines
7.6 KiB
Markdown
只有类组件才有生命周期
|
||
1. 创建
|
||
```html
|
||
class LifeCreate extends React.Component{
|
||
constructor(props){
|
||
super(props)
|
||
console.warn('1.生命周期钩子函数constructor')
|
||
}
|
||
componentDidMount(){
|
||
console.warn('3.生命周期钩子函数componentDidMount')
|
||
}
|
||
render(){
|
||
console.warn('2.生命周期钩子函数render')
|
||
return (<div><h3>hello</h3></div>)
|
||
}
|
||
}
|
||
```
|
||
2. 更新
|
||
New props,setState,forceUpdate
|
||
```html
|
||
class LifeUpdate extends React.Component{
|
||
constructor(props){
|
||
super(props)
|
||
console.warn('1.生命周期钩子函数constructor')
|
||
this.state = {
|
||
count:0
|
||
}
|
||
}
|
||
componentDidMount(){
|
||
console.log(document.getElementById('root'))
|
||
console.warn('3.生命周期钩子函数componentDidMount')
|
||
}
|
||
handlerClick= ()=>{
|
||
// this.setState({
|
||
// count:this.state.count+1
|
||
// })
|
||
this.forceUpdate()
|
||
}
|
||
render(){
|
||
console.warn('2.生命周期钩子函数render')
|
||
return (<div><Counter count = {this.state.count}/><button onClick={this.handlerClick}>hello</button></div>)
|
||
}
|
||
}
|
||
class Counter extends React.Component{
|
||
componentDidUpdate(prevProps){
|
||
console.warn('---------------2生命周期钩子函数componentDidUpdate')
|
||
if(prevProps.count!=this.props.count){
|
||
this.setState({})
|
||
}
|
||
}
|
||
render(){
|
||
console.warn('---------------1生命周期钩子函数render')
|
||
return (<p>点击次数{this.props.count}</p>)
|
||
}
|
||
}
|
||
```
|
||
3. 卸载
|
||
```html
|
||
class LifeEnd extends React.Component{
|
||
constructor(props){
|
||
super(props)
|
||
console.warn('1.生命周期钩子函数constructor')
|
||
this.state = {
|
||
count:0
|
||
}
|
||
}
|
||
componentDidMount(){
|
||
console.log(document.getElementById('root'))
|
||
console.warn('3.生命周期钩子函数componentDidMount')
|
||
}
|
||
handlerClick= ()=>{
|
||
this.setState({
|
||
count:this.state.count+1
|
||
})
|
||
// this.forceUpdate()
|
||
}
|
||
render(){
|
||
console.warn('2.生命周期钩子函数render')
|
||
return (<div>
|
||
{this.state.count>3?("goodby"):<Counter count = {this.state.count}/>}
|
||
<button onClick={this.handlerClick}>hello</button></div>)
|
||
}
|
||
}
|
||
class Counter extends React.Component{
|
||
componentDidUpdate(prevProps){
|
||
console.warn('---------------2生命周期钩子函数componentDidUpdate')
|
||
|
||
if(prevProps.count!==this.props.count){
|
||
this.setState({})
|
||
}
|
||
}
|
||
componentDidMount(){
|
||
this.timerId = setInterval(()=>{
|
||
console.log("定时器在执行")
|
||
},500)
|
||
}
|
||
componentWillUnmount(){
|
||
clearInterval(this.timerId)
|
||
console.warn("结束")
|
||
}
|
||
render(){
|
||
console.warn('---------------1生命周期钩子函数render')
|
||
return (<p>点击次数{this.props.count}</p>)
|
||
}
|
||
}
|
||
```
|
||
# 组件复用
|
||
复用组件的状态逻辑1.state2.操作state的方法.
|
||
## render props
|
||
将要复用的state和操作state的方法封装到一个组件中
|
||
添加一个值为函数的prop,通过函数参数来获取(需要组件内部来实现)
|
||
使用该函数的返回值,作为要渲染的UI内容
|
||
```html
|
||
import img from './img/20200205205324.jpg'
|
||
import PropTypes from "prop-types"
|
||
class RepeatUse extends React.Component {
|
||
render(){
|
||
return (
|
||
<div>
|
||
<h1>render props 复用模式</h1>
|
||
<Mouse >{mouse=>{return (<p>X:{mouse.x},Y{mouse.y}</p>)}}</Mouse>
|
||
<Mouse >{mouse=>{return <img src={img} alt="" style={{position:'absolute',top:mouse.y-350,left:mouse.x-350}} />}}</Mouse>
|
||
</div>
|
||
)
|
||
}
|
||
}
|
||
class Mouse extends React.Component {
|
||
state = {
|
||
x: 0, y: 0
|
||
}
|
||
handleMouseMove = e => {
|
||
this.setState({
|
||
x: e.clientX,
|
||
y: e.clientY
|
||
})
|
||
}
|
||
// 监听鼠标移动
|
||
componentDidMount() {
|
||
window.addEventListener('mousemove', this.handleMouseMove)
|
||
}
|
||
componentWillUnmount(){
|
||
window.removeEventListener('mousemove', this.handleMouseMove)
|
||
}
|
||
render(){
|
||
return this.props.children(this.state)
|
||
}
|
||
}
|
||
Mouse.propTypes={
|
||
children:PropTypes.func.isRequired
|
||
}
|
||
```
|
||
## 高阶组件HOC
|
||
是一个函数,接收要包装的组件,返回增强后的组件
|
||
1. 创建函数以with开头
|
||
2. 指定函数参数,参数大写开头
|
||
3. 函数内部创建类组件,提供复用状态逻辑代码
|
||
4. 在组件中渲染参数组件,同时通过prop传递给参数组件(high order component)
|
||
5. 调用高阶组件,传入要增强的组件,通过返回值拿到增强后的组件并将其渲染到页面.
|
||
```html
|
||
class RepeatUse extends React.Component {
|
||
render(){
|
||
return (
|
||
<div>
|
||
<h1>render props 复用模式</h1>
|
||
<MoousePosition ></MoousePosition>
|
||
</div>
|
||
)
|
||
}
|
||
}
|
||
|
||
function withMouse(WrappedComponent){
|
||
class Mouse extends React.Component {
|
||
state = {
|
||
x: 0, y: 0
|
||
}
|
||
handleMouseMove = e => {
|
||
this.setState({
|
||
x: e.clientX,
|
||
y: e.clientY
|
||
})
|
||
}
|
||
// 监听鼠标移动
|
||
componentDidMount() {
|
||
window.addEventListener('mousemove', this.handleMouseMove)
|
||
}
|
||
componentWillUnmount(){
|
||
window.removeEventListener('mousemove', this.handleMouseMove)
|
||
}
|
||
render(){
|
||
// return this.props.children(this.state)
|
||
return <WrappedComponent {...this.state}></WrappedComponent>
|
||
}
|
||
}
|
||
|
||
return Mouse
|
||
}
|
||
|
||
const Position = props=>(
|
||
<p>
|
||
鼠标当前位置(x:{props.x},y:{props.y})
|
||
</p>
|
||
)
|
||
const MoousePosition = withMouse(Position)
|
||
|
||
```
|
||
### 设置displayName便于区分
|
||
```html
|
||
class RepeatUse extends React.Component {
|
||
render(){
|
||
return (
|
||
<div>
|
||
<h1>render props 复用模式</h1>
|
||
<MoousePosition ></MoousePosition>
|
||
{/* <MoousePosition >{mouse=>{return (<p>X:{mouse.x},Y{mouse.y}</p>)}}</MoousePosition> */}
|
||
{/* <MoousePosition >{mouse=>{return <img src={img} alt="" style={{position:'absolute',top:mouse.y-350,left:mouse.x-350}} />}}</MoousePosition> */}
|
||
</div>
|
||
)
|
||
}
|
||
}
|
||
|
||
function getDisplayName(WrappedComponent){
|
||
return WrappedComponent.displayName || WrappedComponent.name || 'Component'
|
||
}
|
||
|
||
function withMouse(WrappedComponent){
|
||
|
||
class Mouse extends React.Component {
|
||
state = {
|
||
x: 0, y: 0
|
||
}
|
||
handleMouseMove = e => {
|
||
this.setState({
|
||
x: e.clientX,
|
||
y: e.clientY
|
||
})
|
||
}
|
||
// 监听鼠标移动,仅挂载执行一次
|
||
componentDidMount() {
|
||
window.addEventListener('mousemove', this.handleMouseMove)
|
||
}
|
||
componentWillUnmount(){
|
||
window.removeEventListener('mousemove', this.handleMouseMove)
|
||
}
|
||
render(){
|
||
// return this.props.children(this.state)
|
||
return <WrappedComponent {...this.state}></WrappedComponent>
|
||
}
|
||
}
|
||
// 设置展示名称
|
||
Mouse.displayName = `WithMouse${getDisplayName(WrappedComponent)}`
|
||
return Mouse
|
||
}
|
||
|
||
const Position = props=>(
|
||
<p>
|
||
鼠标当前位置(x:{props.x},y:{props.y})
|
||
</p>
|
||
)
|
||
const MoousePosition = withMouse(Position)
|
||
```
|
||
## 高阶组件传递 props
|
||
```html
|
||
render(){
|
||
// return this.props.children(this.state)
|
||
return <WrappedComponent {...this.state}{...this.props}></WrappedComponent>
|
||
}
|
||
```
|
||
## 组件极简模型
|
||
(state,props)=>UI |