概览
Hook只能在函数组件中调用 最后两个hook用的不多(我是没用过),这里就不写了
useState
import Reac , {useState} from 'react'
const App = (params) => {
const [count,setCount] = useState(0)
const handleClick = () => {
setCount(1)
console.log(count)
setCount((count) => {
console.log(count)
count++
console.log(count)
return count
})
setCount(count)
}
console.log(count)
return (
<div>
<div>{count}</div>
<button onClick={handleClick}>按钮</button>
</div>
)
}
useEffect
常用的hook,不做介绍
useContext
作用:向所有的后代传参
import React, {Component , creatContext} from 'react'
const AppContext = creatContext();
class Foo extends Component {
render(){
return (
<AppContent.Consumer>
{value => <div>{values}</div>}
<AppContent.Consumer>
)
}
}
class Bar extends Component {
static contextType = AppContext
render(){
const value = this.context
return (
<div>{value}</div>
)
}
}
const Baz = () => {
const value = useContext(AppContext)
return (
<div>{value}</div>
)
}
const Middle = () => {
return (
<div>
<Foo />
<Bar />
<Baz />
</div>
)
}
const App = (params) => {
return (
<AppContext.Provider value='fanghui'>
<Middle />
<AppContext.Provider>
)
}
useReducer
作用:处理一些复杂的更加复杂的state运算
import Reac , { useReducer } from 'react'
const App = (params) => {
const countReducer = (action,state) => {
switch(action.type){
case 'add':
return state + 1
case 'sub':
return state - 1
default:
return state
}
}
const [count,dispatchCount] = useReducer(0)
const add = () => {
dispatchCount({type:'add'})
}
const sub = () => {
dispatchCount({type:'sub'})
}
return (
<div>
<div>{count}</div>
<button onClick={add}>加1</button>
<button onClick={sub}>减1</button>
</div>
)
}
useMemo 和 useCallback
一种性能优化的手段
import React, { useState, useMemo, useCallback, memo } from "react"
const Foo = memo(props => {
console.log("Foo render");
return (
<div>
<ul>{props.render()}</ul>
{props.count}
</div>
)
})
const App = () => {
const [range, setRange] = useState({ min: 0, max: 10000 });
const [count, setCount] = useState(0);
const render = useCallback(
params => {
let list = [];
for (var i = 0; i < range.max; i++) {
list.push(<li key={i}>{i}</li>);
}
return list;
},
[range]
);
return (
<div>
<h1>{count}</h1>
<button
onClick={() => {
setRange({
...range,
max: range.max + 1
});
}}
>
add
</button>
<Foo render={render}></Foo>
</div>
);
}
useRef
提到useRef,我们不得不再提下creatRef
- 都可以获取原生DOM
import Reac , { creatRef, useRef } from 'react'
const FuncComp = (params) => {
const inputRef = creatRef()
const inputRef = useRef()
return (
<div>
<input ref=() />
<button onClick={inputRef}>聚焦</button>
</div>
)
}
- useRef和creatRef的区别
当子组件是类组件时
import Reac , { creatRef, useRef,Component } from 'react'
class ChildClassComp extends Component {
const inputRef = creatRef()
focusInput = () => {
inputRef.current.foucs()
}
render(){
return (
<div>
<input ref={inputRef} />
<button onClick={focusInput}>聚焦</button>
</div>
)
}
}
class ClassComp extends Component {
const childRef = creatRef()
conponentDidMount(){
childRef.current.focusInput()
}
render(){
return (
<div>
<ChildClassComp ref={childRef}/>
<button onClick={inputRef}>聚焦</button>
</div>
)
}
}
当子组件是函数组件时
import Reac , { creatRef, useRef,Component,forwordRef } from 'react'
const ChildFuncComp = forwordRef ((props,ref) => {
return (
<div>
<input ref={ref} />
<button onClick={focusInput}>聚焦</button>
</div>
)
})
class ClassComp extends Component {
const childRef = creatRef()
conponentDidMount(){
childRef.current.focus()
}
render(){
return (
<div>
<ChildClassComp ref={childRef}/>
<button onClick={inputRef}>聚焦</button>
</div>
)
}
}
刚学的时候,还是蛮绕的,通过Js++集团得小夏老师的讲解终于弄懂了,感谢 !
总结 :
- creatRef创建ref容器,既可以绑定类组件也可以绑定函数组件,但是当函数组件每次重新渲染时,它所创建的ref的引用都是新的,所以我们在函数组件里更推荐使用useRef,它每次创建出来的ref的引用都是一样的,性能更高。而类组件里别无选择,只能使用creatRef,它也只会在类组件里执行一次,ref的引用都是一样的。
- 不论是useRef还是creatRef创建出来的ref绑定在类组件身上的时候,获取的是绑定类组件本身的实例,而当绑定的是函数组件的时候,只能使用forwordRef来转发到函数子组件里的具体DOM元素(我记的别的文章也叫穿透ref)
useImperativeHandle
前提:学会这个useImperativeHandle前,你需要学会useRef这个hook
作用:在项目中,别人调用我们写的子组件时,需要知道我们这个子组件所暴露给父组件的实例值,useImperativeHandle 应当与 forwardRef 一起使用
import Reac , { creatRef, useRef,Component,forwordRef } from 'react'
const ChildFuncComp = forwordRef ((props,ref) => {
const inputRef = useRef()
useImperativeHandle(ref,() => {
return {
customerFocus: () => {
inputRef.current.focus();
},
sayHello: () => {
console.log('Hello World')
}
}
})
return (
<div>
<input ref={inputRef} />
<button onClick={focusInput}>聚焦</button>
</div>
)
})
class ClassComp extends Component {
const childRef = creatRef()
conponentDidMount(){
childRef.current.customerFocus()
childRef.current.sayHello()
}
render(){
return (
<div>
<ChildClassComp ref={childRef}/>
<button onClick={inputRef}>聚焦</button>
</div>
)
}
}
未完,待续…(可能)
|