react函数组件与hooks
组件每次更新时都会重新执行函数
HOOK介绍
每次渲染时它们的调用顺序是不变的
你可以在一个组件中多次使用 State Hook:
- React 函数组件中
- React 自定义 Hook 中
- 只在最顶层使用 Hook:在 React 中要保证 hook 的执行顺序,组件前和更新后 hook 的执行顺序要保持一致
useState
接受初始状态值,可以是任何数据类型。返回一个数组,分别为状态值和修改状态值的方法。
同样会受到批处理影响,多次使用 setState 会被合并只执行一次更新。
初始 state 参数只有在第一次渲染时会被用到。
setState可以接受新值,也可以接受函数,入参为更新前的值,返回新值。
function Counter({initialCount}) {
const [count, setCount] = useState(initialCount);
return (
<>
Count: {count}
<button onClick={() => setCount(initialCount)}>Reset</button>
<button onClick={() => setCount(prevCount => prevCount - 1)}>-</button>
<button onClick={() => setCount(prevCount => prevCount + 1)}>+</button>
</>
);
}
惰性初始 state:如果初始 state 需要通过复杂计算获得,则可以传入一个函数,在函数中计算并返回初始的 state,此函数只在初始渲染时被调用:
const [state, setState] = useState(() => {
const initialState = someExpensiveComputation(props);
return initialState;
});
需要解构赋值
function App() {
const [person, setPerson] = useState({ name: 'le', age: 18 })
function handleCount() {
setCount(() => count + 1)
document.title = count//title是加1前的值
}
return (
<div>
{count}
{person.name + ':' + person.age}
<button onClick={() => setPerson({ ...person, age: person.age + 1 })} >年龄加1</button>
</div>
)
}
Effect Hook
一般用于处理副作用(数据获取、订阅或者手动修改过 DOM等)。
挂载阶段:
依次将 effect 函数,存储到一个队列中,当组件挂载完成之后,依次执行 effect 队列,获取 cleanup 函数,将 cleanup 函数存入一个队列。
更新阶段:
依次将 effect 函数,存储到一个队列中,当组件更新完成之后,找到 cleanup 队列,依次执行。按添加顺序执行 effect 队列,获取 cleanup 函数,将 cleanup 函数存入一个队列。(useEffect 对应的依赖数据如果没变化,不执行)
卸载阶段:
依次执行cleanup 队列
依赖参数:
无依赖参数, 组件有更新,就会执行其 cleanup 函数 和 effect 函数
空数组依赖,则组件更新时,不会执行其 cleanup 和 effect
有具体依赖参数,则组件更新时,其依赖参数有变化,会执行其 cleanup 函数 和 effect 函数
useEffect(() => {
console.log("无依赖");
return () => {
console.log("cleanup-无依赖");
}
});
useEffect(() => {
console.log("依赖空数组");
return () => {
console.log("cleanup-依赖空数组");
}
}, []);
useEffect(() => {
console.log("依赖数据");
return () => {
console.log("cleanup-依赖数据");
}
}, [val, count]);
useContext
接受context,由距离当前组件最近的 <MyContext.Provider>
的 value
prop 决定。
//创建context文件
import {createContext} from "react";
const context = createContext();
//使用context函数
import {useContext} from "react";
const value = useContext(context);
useRef
function TextInputWithFocusButton() {
const inputEl = useRef(null);
const onButtonClick = () => {
// `current` 指向已挂载到 DOM 上的文本输入元素
inputEl.current.focus();
};
return (
<>
<input ref={inputEl} type="text" />
<button onClick={onButtonClick}>Focus the input</button>
</>
);
}