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
|