内容简介:React Hooks 是React 16.7.0-alpha 版本推出的新特性。从 16.8.0 开始,React更稳定的支持了这一新特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性。注意:React 16.8.0 是第一个支持 Hook 的版本。升级时,请注意更新所有的 package,包括 React DOM。React Native 将在下一个稳定版本中支持 Hook。
React Hooks 是React 16.7.0-alpha 版本推出的新特性。从 16.8.0 开始,React更稳定的支持了这一新特性。
它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性。
注意:React 16.8.0 是第一个支持 Hook 的版本。升级时,请注意更新所有的 package,包括 React DOM。React Native 将在下一个稳定版本中支持 Hook。
如果说promise是JavaScript异步的终极解决方案,那么React Hooks从某种意义上来说,也是react状态管理的终极解决方案。
为什么用 React Hooks?与其他状态管理方案有什么区别?
在react hooks,react态管理方案主要有如下2种:
这两种状态解决方案其实已经很不错,可以满足绝大多数状态共享的业务场景。 当然,像FB这样优秀的团队优秀的人总喜欢钻研,不断优化。认为这两种状态解决方案嵌套太多,很多业务逻辑可以抽象出来。不仅仅是共享状态就完事了,还得共享出处理逻辑。 为了减少不必要的组件嵌套写法,实现更扁平、颗粒化的状态 + 逻辑的复用,于是便推出了 React Hooks 。
关于react hooks,具体可以多看看React Hooks官方文档,理解会更深。
业务实战1:实现一个简单的显示隐藏弹出框
1、基于 render-props实现:
// 将父组建的 on状态 和toggle 事件,共享给嵌套下的子组件 function App() { return ( <Toggle initial={false}> {({ on, toggle }) => ( <Button type="primary" onClick={toggle}> Open Modal </Button> <Modal visible={on} onOk={toggle} onCancel={toggle} /> )} </Toggle> ) } 复制代码
2、用react hooks实现
import React, { useState } from 'react'; function Example() { // 声明一个新的叫做 “visible” 的 state 变量 const [visible, setVisible] = useState(false); return ( <div> <Modal onClick={() => setVisible(!visible)}> Click me </Modal> </div> ); } 复制代码
业务实战2: 接收传入props后立马更新自有的State状态(received passed props and updated)
function Avatar(props) { const [user, setUser] = React.useState({...props.user}); // 这里仅仅是给了一个初始值,仅第一次渲染的时候生效,后续都不会再更新了。 // 用useEffect,第二个参数传入一个数组字段props.user, // 表示每次只要传入的props.user有变化,那么就触发setUser这个操作更新状态。 React.useEffect(() => { setUser(props.user); }, [props.user]) return user.avatar ? (<img src={user.avatar}/>) : (<p>Loading...</p>); } 复制代码
由上述例子可以看到,我们用到了useEffect这个hooks。
Effect Hook 可以让你在函数组件中执行副作用操作
什么叫副作用呢? 数据获取,设置订阅以及手动更改 React 组件中的 DOM 都属于副作用。
如果实在理解不了副作用,你可以理解为,在我们在写传统的react class组件里面的生命周期钩子函数componentDidMount,componentDidUpdate 和 componentWillUnmount 这三个函数的组合中处理的相关逻辑,就是副作用。
也就是说,任何你想在页面首次加载完(componentDidMount),后续每次更新完(componentDidUpdate),亦或者是组件卸载前(componentWillUnmount),这三个勾子中加入你自己的逻辑处理,就得用到useEffect
业务实战3:显示后,倒计时自动隐藏(与setInterval结合)
业务场景具体如下:实现一个倒计时30秒,每秒钟减1,然后倒计时完毕这个组件自动隐藏。
function App() { const [count, setCount] = useState(30); useEffect(() => { setInterval(() => { setCount(count - 1); }, 1000); }); return <div className="App">{count}</div>; } 复制代码
看看上述的写法,自己运行一下就只知道了,肯定是大错特错的。 最基本的,setInterval这个删除定时器都没有做相关处理。 其次,每次都会生成不同都setInterval实例。那么如何加以控制呢?
来看看正确都写法,这里要用到useRef这种类型都hooks了。
function App(props){ const [visible,setVisible] = useState(false);// 初始化值为false,隐藏 const [count,setCount] = useState(0); // 倒计时字段,初始值为0 // 明确定时器要做什么:我们这里是每秒 -1,小于等于0的时候就自动给隐藏 // 同时,本此的跟新跟下次的渲染更新要共享状态,记住上次更新这个count减到哪里了 // 基于上述问题,我们可以使用如下方案: // 声明一个useRef对象,初始化为null const intervalCb = useRef(null); useEffect(()=>{ // useRef 对象有一个current属性,可以给它赋值为一个函数 intervalCb.current = () => { if(count <= 0){ setVisible(false); }else{ setCount(count - 1); } }; }) // 在componentDidMount中设置一个定时器 useEffect(()=>{ function itvFn(){ // 在此前,定时器的回调函数已经声明,这里可以直接调用 intervalCb.current(); } const itvId = window.setInterval(itvFn,1000); // return 一个回调函数,表示清除处理 return () => window.clearInterval(itvId); },[]) // 传入要监听的对象,空数组表示只监听一次,相当于didMounted } return (<div className={visible}> {count} </div>) } 复制代码
关于useRef 更多的请看useRef官方文档
业务实战4: 自定义hooks
基于上述setInterval的业务功能实现,我们简单的来写一个自定义的hooks
export default function useInterval(callback) { const savedCallback = useRef(); useEffect(() => { savedCallback.current = callback; }); useEffect(() => { function tick() { savedCallback.current(); } let id = setInterval(tick, 1000); return () => clearInterval(id); }, []); } 复制代码
然后在你需要用到的地方引入:
import useInterval from 'xx/self_hooks'; function App(){ useInterval(()=>{ // ... 跟useEffect写法类似,目前只支持传入一个function类型的参数,如果要接收多个参数,那么在自定义hooks那里去自行处理一下。 }) } 复制代码
关于自定义hooks,更多请查看自定义hooks
暂结
关于react hooks 简单的使用,此篇就暂时写到这里,当然,复杂一点的,可以使用useReducer、useContext和useEffect代替Redux方案。后续我们应该单独来研究这块。 回顾一下,如何才能说我们会用react hooks 呢?
- 第一、明白概念,干什么用的,解决哪些痛点?
- 第二、useEffect传入几个参数?分表表示声明?useRef作用是什么?这些可以解决我们基本的业务需求。
- 第三、useReducer、useContext 怎么替换 redux?
- 读源码,搞清楚为什么useEffect不能卸载if嵌套中等之类的问题?
今天先把问题抛出,后续按照这个,循序渐进的学习掌握react hooks。
以上所述就是小编给大家介绍的《React Hooks简单业务场景实战(非源码解读)》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 专家实战解读 Flutter for Web
- 十余行代码完成迁移学习,百度PaddleHub实战解读
- 技术解读 | 基于fastText和RNN的语义消歧实战
- Phoenix解读 | Phoenix源码解读之索引
- Phoenix解读 | Phoenix源码解读之SQL
- Flink解读 | 解读Flink的声明式资源管理与自动扩缩容设计
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。