文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

React从Class方式转Hooks详解

2024-04-02 19:55

关注

React Hooks

前言

之前工作三年中一直在用class方式去写前端功能页面这些,其实接触hooks也是有一定时间了。在第一次接触的时候应该是看了一门关于electron+react的项目的课程的时候。当时主要是去看electron,所以对hooks没有特别的关注。也有可能是长期以来对class的熟悉,当时对hooks这种函数式的写法也有一些抵触。但是由于业内对hooks的好评,曾经也想去用hooks去起一个项目,但是由于当时项目周期以及已有的技术栈等原因,一直想实践也没机会去实践使用。

由于,最近接手新的项目一直使用的是react hooks+ts这一套。于是,就得开始使用hooks了。其实就功能开发而言,照猫画虎,其实工作也没有什么问题的。但是由于一直没有系统的对hooks进行深入一步的了解,导致在很多时候,其实并不是很清楚为什么要这样去使用,于是最近去找了《React Hooks核心原理与实战》去进行了学习。

在使用层面以及原因层面上,重新审视hooks的使用以及为什么要使用hooks。函数式写法究竟有哪些好处进行了更进一步的思考。其实,在一定程度而言,也还是浅尝辄止,这里仅仅将我这段时间学习记录下来。

Why Hooks ?

Hooks很大的一个亮点是可以进行业务逻辑的重用。这一点在hooks中体现的尤为明显。比如,往常的class中如果要去监听窗口大小的变化的时候,就得在组件中在挂载后去添加监听事件,但是如果当另外一个地方需要用到这种监听窗口大小功能的话,这种逻辑代码并不可以复用,只能在那个组件中重新写一遍。但是在hooks中,我们可以将这部分监听的逻辑代码进行hooks方式封装,完全可以做到逻辑上的复用。

For Class

For Function

React中的一个核心就是要实现从State数据到View试图层面的一个绑定。使用函数,其实更好的去解决State到View的一个映射问题。但是,用函数作为React的载体就会出现两个问题,函数中状态的保存以及生命周期的方法

图解:一个执行过程(Execution),例如是函数组件本身,可以绑定在(钩在)传统意义的 State,或者 URL,甚至可以是窗口的大小。这样当 State、URL、窗口大小发生变化时,都会重新执行某个函数,产生更新后的结果。

Class & Hooks 对比


//Class中高阶组件实现resize方法复用
//1、高阶组件的声明
const withWindowSize = Component => {
  // 产生一个高阶组件 WrappedComponent,只包含监听窗口大小的逻辑
  class WrappedComponent extends React.PureComponent {
    constructor(props) {
      super(props);
      this.state = {
        size: this.getSize()
      };
    }
    componentDidMount() {
      window.addEventListener("resize", this.handleResize); 
    }
    componentWillUnmount() {
      window.removeEventListener("resize", this.handleResize);
    }
    getSize() {
      return window.innerWidth > 1000 ? "large" :"small";
    }
    handleResize = ()=> {
      const currentSize = this.getSize();
      this.setState({
        size: this.getSize()
      });
    }
    render() {
      // 将窗口大小传递给真正的业务逻辑组件
      return <Component size={this.state.size} />;
    }
  }
  return WrappedComponent;
};
//2、组件MyComponent使用高阶组件中的resize功能
class MyComponent extends React.Component{
  render() {
    const { size } = this.props;
    if (size === "small") return <SmallComponent />;
    else return <LargeComponent />;
  }
}
// 使用 withWindowSize 产生高阶组件,用于产生 size 属性传递给真正的业务组件
export default withWindowSize(MyComponent); 

//Hooks中使用hooks方法进行resize逻辑复用
//定义useWindowSize这个hook
const getSize = () => {
  return window.innerWidth > 1000 ? "large" : "small";
}
const useWindowSize = () => {
  const [size, setSize] = useState(getSize());
  useEffect(() => {
  const handler = () => {
      setSize(getSize())
    };
    window.addEventListener('resize', handler);
    return () => {
      window.removeEventListener('resize', handler);
    };
  }, []);
  return size;
};
//函数组件中使用这个hook
const Demo = () => {
  const size = useWindowSize();
  if (size === "small") return <SmallComponent />;
  else return <LargeComponent />;
};

Hooks能够让针对同一个业务逻辑的代码尽可能聚合在一块,在Class组件中不得不吧同一个业务逻辑代码分散在类组件的不同的生命周期方法中

img

图解:左侧是 Class 组件,右侧是函数组件结合 Hooks。蓝色和黄色代表不同的业务功能

Hooks如何保存组件状态和使用生命周期?

React一共提供了10个HooksuseStateuseEffectuseCallbackuseMemouseRefuseContext等等

1、useState:让函数具有维持状态的能力

我们要遵循的一个原则就是:state 中永远不要保存可以通过计算得到的值,例如:

2、useEffect:执行副作用

副作用是指一段和当前执行结果无关的代码。比如说要修改函数外部的某个变量,要发起一个请求。形式:useEffect(callback, dependencies)。涵盖了componentDidMountcomponentDidUpdatecomponentWillUnmount三个生命周期方法。简而言之,useEffect 是每次组件 render 完后判断依赖并执行。

使用useEffect应该注意的点:

没有依赖项,则每次 render 后都会重新执行


useEffect(()=>{
	console.log('re-render')		//每次render完成一次后就执行
})

useEffect(()=>{
  console.log('did mount')		//相当于componentDidMount
},[])

const [size,setResize] = useState({})
useEffect(()=>{
	const handler = () => {
    setResize()
	}
	window.addEventListener('resize',handler)
	return ()=>{
		window.removeEventListener('resize',handler)
	}
},[])

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注编程网的更多内容!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-前端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯