React 基础笔记 04
React Hooks
使用 hooks 的理由
- 高阶组件为了复用,导致代码层级复杂
- 生命周期复杂
- 写成 function 组件,无状态组件
useState (保存组件状态)
const [name,setName] = useState('smiling')
useEffct (处理副作用) 和 useLayoutEffect (同步执行副作用)
区别:useLayoutEffect 在 React 完成 DOM 更新后马上同步调用的代码,会阻塞页面渲染;useEffct 是在整个页面渲染完才会调用的代码。
函数组件中不存在生命周期。
- useEffct 传空数组,useEffct 内部,函数体里面只执行一次
import React, { useEffect, useState } from "react";
function App() {
const [name, setName] = useState('smiling')
useEffect(()=>{
console.log(name)
},[])
return (<>
<div>{name}</div>
</>);
}
export default App;
- useEffct 传值,当值发生改变,useEffct 内部,函数体里面只执行
import React, { useEffect, useState } from "react";
function App() {
const [name, setName] = useState('smiling')
// 点击按钮修改 name
const onclick = () => {
setName('wangling')
}
// 当 name 改变将首字母大写
useEffect(()=>{
const str = name.substring(0,1).toUpperCase() + name.substring(1)
setName(str)
},[name])
return (<>
<div>{name}</div>
<button onClick={onclick}>修改名字</button>
</>);
}
export default App;
useCallback (记忆函数)
防止因为组件重新渲染,导致方法被重新创建,起到缓存作用;只有第二个参数变化了,才重新声明一次。
function App() {
const [name, setName] = useState('smiling')
const onclick = useCallback(()=>{
console.log(name)
},[name])
return (<>
<div>{name}</div>
<button onClick={onclick}>查看</button>
</>);
}
export default App;
useMemo (记忆组件)
useCallback 的功能完全可以由 useMemo 取代,如果想使用 useMemo 返回一个记忆函数也是可以的。
区别: useCallback 不会执行第一个参数函数,而是返回一个函数,useMemo 会执行第一个函数并且将函数执行的结果返回。 因此,useCallback 常用于记忆事件函数,生成记忆后事件函数传递给子组件使用。useMemo 更适合经过函数计算得到的一个确定的值。
useRef (保存引用值)
function App() {
const mytext = useRef() // React.createRef()
const handChange = (e) => {
console.log(e.target.value) // 获取输入框的值
}
return (<>
<input ref={mytext} onChange={handChange} />
</>);
}
export default App;
useReducer 和 useContext (减少组件层级)
useContext 可以跨越组件层级直接传递变量,实现数据共享。
useContext 和 redux 的区别: useContext : 用于解决组件之间传值的问题; redux : 统一管理应用状态。 可以使用 useContext 结合 useReducer 模拟一个小型的 redux 场景。
import React, { useState, createContext, useContext } from "react";
const CountContext = createContext(0); // 创建 Context
const App = () => {
const [count, setCount] = useState(0);
return (
<div>
<p>父组件点击数量:{count}</p>
<button onClick={() => setCount(count + 1)}>{"点击+1"}</button>
// CountContext.Provider 包裹需要接收参数的子组件,并通过 value 传值
<CountContext.Provider value={count}>
<Counter />
</CountContext.Provider>
</div>
);
};
const Counter = () => {
// 子组件通过 useContext 把刚刚创建好的 CountContext 作为参数传进去,并读取 count 值
const count = useContext(CountContext);
return <p>子组件获得的点击数量:{count}</p>;
};
export default App;
useReducer : 是 React 提供的一个高级 Hook,可以使我们的代码又更好的可读性、可维护性、可预测性。
reducer 是一个函数 (state, action) => {} 接受当前应用的 state 和 触发的动作 action, 计算并返回最新的 state。
import React, { useReducer } from "react";
const App = () => {
// 执行的操作
const reducer = (preState,action) =>{
const newState = {...preState}
switch(action.type){
case 'add':
newState.cont ++
return newState
case 'minus':
newState.cont --
return newState
}
}
// 初始化状态
const initalState = {
cont: 0,
}
const [state, dispatch] = useReducer(reducer,initalState)
return (
<div>
<button onClick={()=>{
dispatch({
type: 'minus'
})
}}>-</button>
{state.cont}
<button onClick={()=>{
dispatch({
type: 'add'
})
}}>+</button>
</div>
);
};
自定义 hooks
自定义 hooks 实际上就是把每个组件中重复的逻辑单独抽离出来,然后封装成函数。必须使用 use 开头,不然使用不了一些 hooks
- @Title: React 基础笔记 04
- @Content: React
- @Autor: ling.wang
- @StudyDate: 2022-07-06
- @WritingDate: 2022-07-06