Hooks使用
1.useContext:组件层级进行传值 (父子组件之间进行传值)
区别于redux
redux是统一管理状态
useContext是组件共享数据 通过它包裹的组件 可以直接使用这个里面的值
使用
import { createContext,useContext } from 'react'
const TestContext = createContext({}) // 里面也可以是string类型
const M1 = () => {
const { name } = useContext(TestContext)
return (
<div>{name}</div>
)
}
const M2 = () => {
const { name } = useContext(TestContext)
return (
<div>{name}</div>
)
}
const Detail = () => {
return (
<div>
<TestContext.Provider
value={{name:'tom'}}
>
<M1/>
<M1/>
</TestContext.Provider>
</div>
)
}
export default withRouter(Detail) // 导出
2.useReducer
const [最新的state,dispatch(派发action的)] = useReducer(()=>{},初始的state值)
eg:
function ReducerDemo(){
const [count, dispatch] = useReducer((state,action) => {
switch(action){
case 'add':
return state+1;
case 'sub':
return state-1;
default:
return state;
}
},0)
return (
<div>
<h2>最新的数值{count}</h2>
<button onClick={()=>dispatch('add')}>加</button>
<button onClick={()=>dispatch('sub')}>减</button>
</div>
)
}
useCallback (对函数的缓存优化 缓存一个函数)
使用场景: 就是父组件加载子组件 每次父组件的state发生改变了,子组件都要重新加载一次 从头到尾加载 这个时候如果子组件里面有函数,那么函数又要重新创建一次 会生成新的地址引用 占用空间内存
说明:
这个useCallback只是缓存了一个函数 避免函数重新创建
用法:useCallback(fn(),[依赖的属性值]) 第二个参数可以为空 为空就代表只是创建一次 以后不会重新创建了
例子1:
// 定义一个子组件
const Child = (props) => {
const submit = useCallback(
() => {
console.log('执行函数 重新创建的一个函数')
},[age]
)
return (
<div onClick={submit}>子组件{props.name}</div>
)
}
// 定义一个父组件
const Parent = () => {
const [name,setName] = useState('')
const [age,setAge] = useState()
const handleChange = () => {
setName('kk');
}
return (
<Button onClick={handleChange}>改变名称</Button>
<Child age={age} name={name}/>
)
}
这个例子就是父组件点击改变了name的值 组件都要重新加载 包括子组件 这个时候传递给子组件的属性name虽然改变了
但是useCallback依赖的属性是age age并没有发生改变 所以子组件的submit函数就不会重新创建
例子2:
// 定义一个子组件
const Parent = React.memo(({a,c}) => {
console.log('渲染parent组件')
return (
<div onClick={c}>子组件{props.name}</div>
)
})
// 定义一个父组件
const APP = () => {
const [a,setA] = useState(0)
const [b,setB] = useState(1)
const handleClick = () => { console.log('重新创建的函数') } // 无优化的函数 每次都要重新创建了
// 优化的函数 const handleClick = useCallback(() => console.log('重新创建的函数'),[] )
return (
<>
<Parent a={a} c={handleClick}/>
<Button onClick={() => setA(a+1)}>改变了a</Button>
<Button onClick={() => setB(b+1)}>改变了b</Button>
<Button onClick={handleClick}>点击事件</Button>
</>
)
}
这个例子 React.memo优化的结果就是 只有属性a和c 属性任何一个发生改变的时候 这个Parent组件才会重新加载 下面的APP组件创建的函数如果是一个普通创建的函数 那么每次state改变的时候 这个函数都要重新创建 这个时候传递给Parent的c这个值就会发生改变 此时Parent组件又要重新渲染了 所以优化要使用useCallback 这样函数不管当前的组件state发生什么变化 该函数只是创建一次 所以此时只要是传递给Parent的a不发生任何变化 那么子组件Parent就不会重新渲染了
自定义Hooks
hooks约束
Hooks必须要以use命名开头