React 提供的 Hooks 其实非常少,一共只有 10 个,比如 useState、useEffect、useCallback、useMemo、useRef、useContext 等等。这一讲我们会先学习 useState 和 useEffect 这两个最为核心的 Hooks。下一讲则会介绍另外四个常用的 Hooks。掌握了这些 Hooks,你就能进行 90% 的 React 开发了。
useState:让函数组件具有维持状态的能力
可以说,state 是 React 组件非常重要的一个机制,那么什么样的值应该保存在 state 中呢?这是日常开发中需要经常思考的问题。通常来说,我们要遵循的一个原则就是:state 中永远不要保存可以通过计算得到的值。比如说:
1,从 props 传递过来的值。有时候 props 传递过来的值无法直接使用,而是要通过一定的计算后再在 UI 上展示,比如说排序。那么我们要做的就是每次用的时候,都重新排序一下,或者利用某些 cache 机制,而不是将结果直接放到 state 里。
2,从 URL 中读到的值。比如有时需要读取 URL 中的参数,把它作为组件的一部分状态。那么我们可以在每次需要用的时候从 URL 中读取,而不是读出来直接放到 state 里。
3,从 cookie、localStorage 中读取的值。通常来说,也是每次要用的时候直接去读取,而不是读出来后放到 state 里。
useEffect:执行副作用
什么是副作用呢?通常来说,副作用是指一段和当前执行结果无关的代码。比如说要修改函数外部的某个变量,要发起一个请求,等等。也就是说,在函数组件的当次执行过程中,useEffect 中代码的执行是不影响渲染出来的 UI 的。
useEffect 可以接收两个参数,函数签名如下:
useEffect(callback, dependencies)
第一个为要执行的函数 callback,第二个是可选的依赖项数组 dependencies。其中依赖项是可选的,如果不指定,那么 callback 就会在每次函数组件执行完后都执行;如果指定了,那么只有依赖项中的值发生变化的时候,它才会执行。对应到 Class 组件,那么 useEffect 就涵盖了 ComponentDidMount、componentDidUpdate 和 componentWillUnmount 三个生命周期方法。不过如果你习惯了使用 Class 组件,那千万不要按照把 useEffect 对应到某个或者某几个生命周期的方法。你只要记住,useEffect 是每次组件 render 完后判断依赖并执行就可以了。
useEffect 还有两个特殊的用法:没有依赖项,以及依赖项作为空数组。我们来具体分析下。
1,没有依赖项,则每次 render 后都会重新执行。例如:
2,空数组作为依赖项,则只在首次执行时触发,对应到 Class 组件就是 componentDidMount。
除了这些机制之外,useEffect 还允许你返回一个函数,用于在组件销毁的时候做一些清理的操作。比如移除事件的监听。这个机制就几乎等价于类组件中的 componentWillUnmount。
举个例子,在组件中,我们需要监听窗口的大小变化,以便做一些布局上的调整:
// 设置一个 size 的 state 用于保存当前窗口尺寸 const [size, setSize] = useState({}); useEffect(() => { // 窗口大小变化事件处理函数 const handler = () => { setSize(getSize()); }; // 监听 resize 事件 window.addEventListener('resize', handler); // 返回一个 callback 在组件销毁时调用 return () => { // 移除 resize 事件 window.removeEventListener('resize', handler); }; }, []);
总结一下,useEffect 让我们能够在下面四种时机去执行一个回调函数产生副作用:
1,每次 render 后执行:不提供第二个依赖项参数。
2,比如useEffect(() => {})。仅第一次 render 后执行:提供一个空数组作为依赖项。
3,比如useEffect(() => {}, [])。第一次以及依赖项发生变化后执行:提供依赖项数组。
4,比如useEffect(() => {}, [deps])。组件 unmount 后执行:返回一个回调函数。比如useEffect() => { return () => {} }, [])。
标签:执行,函数,笔记,react,hook,state,依赖,组件,useEffect From: https://www.cnblogs.com/wjyz/p/16926770.html