React函数组件与类的区别有哪些React

functionApp(props){constshowMessage=()=>{alert('Hello'+props.user);};consthandleClick=()=>{setTimeout(showMessage,3000);};return(Say);}它渲染了一个利用来模拟网络请求,然后显示一个确认警告的按钮。例如,如果是传递进来的props.user是jie,那么三秒后就会弹出Hellojie。

那么我们用类应该怎么写这个组件呢?一个简单的重构可能就象这样:

classAppextendsReact.Component{showMessage=()=>{alert('Hello'+this.props.user);};handleClick=()=>{setTimeout(this.showMessage,3000);};render(){returnSay;}}我们通常做代码重构的时候都认为他们两个是等效的,但是事实真的如此吗,我们很少注意到它们之间的含义。

下面我们新建一个react项目,在src下新建两个组件,一个classComponent组件,一个是functionComponent组件。代码就是上面我们写的这两个组件,只不过内容稍有区别:

classComponent:

importReactfrom'react';classProfilePageextendsReact.Component{showMessage=()=>{alert('你选择了'+this.props.user);};handleClick=()=>{setTimeout(this.showMessage,3000);};render(){return选择;}}exportdefaultProfilePage;functionComponent:

importReactfrom'react';functionProfilePage(props){constshowMessage=()=>{alert('你选择了'+props.user);};consthandleClick=()=>{setTimeout(showMessage,3000);};return(选择);}exportdefaultProfilePage;在app.js中我们将这两个组件引入:

importReactfrom"react";importReactDOMfrom"react-dom";importProfilePageFunctionfrom'./functionComponent';importProfilePageClassfrom'./classComponent';exportdefaultclassAppextendsReact.Component{state={user:'小杰',};render(){return(<>

欢迎来到{this.state.user}的家!

(这是来自函数式组件的)

(这是来自类组件的)

)}}运行项目,科研看到这样的界面:

当我们单击上面的按钮时,执行的就是函数式组件,点击下面的按钮时,执行的就是类。如果按照我们以往的思路,他们二者都会有相同的结果,但事实真的如此吗?

我们按照下面的顺序执行:

1.点击函数式组件按钮

2.在点击后立刻切换想要拜访的朋友

函数式组件的执行结果如下:

页面弹出的还是我们当时选择的值

同样的操作我们再试一下类组件:

现在页面弹出的就是我们实时更改的值了。

在这个例子中,第一个行为是正确的。因为最开始我选择要拜访小杰点击了确定发出了命令,然后我再切换到小尚,但是我并没有点击确定,我的组件不应该混淆我要拜访的人。在这里,类组件的实现很明显是错误的。

所以为什么我们的例子中类组件会有这样的表现?

让我们来仔细看看我们类组件中的方法:showMessage

showMessage=()=>{alert('你选择了'+this.props.user);};这个类方法从中读取数据。在React中Props是不可变的,所以他们永远不会改变。然而,this是,而且永远是,可变的。

我们的组件属于一个拥有特定props和state的特定渲染。

然而,调用一个回调函数读取的timeout会打断这种关联。我们的回调并没有与任何一个特定的渲染绑定在一起,所以它失去了正确的props。

我们想要以某种方式“修复”拥有正确props的渲染与读取这些props的回调之间的联系。它们在类的某个地方被弄丢了。

一种方法是在调用事件之前读取,然后将他们显式地传递到timeout回调函数中去:

然而,如果我们能利用JavaScript闭包的话问题将迎刃而解。

通常来说我们会避免使用闭包,但是在React中,props和state是不可变的,这就消除了闭包的一个主要缺陷。

这就意味着如果你在一次特定的渲染中捕获那一次渲染所用的props或者state,你会发现他们总是会保持一致,就如同你的预期那样。

classProfilePageextendsReact.Component{render(){constprops=this.props;constshowMessage=()=>{alert('你选择了'+props.user);};consthandleClick=()=>{setTimeout(showMessage,3000);};return确定;}}你在渲染的时候就已经“捕获”了props。这样,在它内部的任何代码(包括)都保证可以得到这一次特定渲染所使用的props。上面的例子是正确的,但是看起来很奇怪。如果你在方法中定义各种函数,而不是使用class的方法,那么使用类的意义在哪里?

所以这个时候我们就明白了函数式组件和类组件的区别:

functionProfilePage({user}){constshowMessage=()=>{alert('Followed'+user);};consthandleClick=()=>{setTimeout(showMessage,3000);};return(Follow);}当父组件使用不同的props来渲染时,React会再次调用函数。但是我们点击的事件处理函数,"属于"具有自己的值的上一次渲染,并且回调函数也能读取到这个值。它们都保持完好无损。

使用Hooks,同样的原则也适用于状态。看这个例子:

functionMessageThread(){const[message,setMessage]=useState('');constshowMessage=()=>{alert('Yousaid:'+message);};consthandleSendClick=()=>{setTimeout(showMessage,3000);};consthandleMessageChange=(e)=>{setMessage(e.target.value);};return(<>Send);}如果我发送一条特定的消息,组件不应该对实际发送的是哪条消息感到困惑。这个函数组件的变量捕获了我们在浏览器中执行单击处理函数的那一次渲染。所以当我点击“发送”时那一刻输入框中的内容就会被设置为弹出的值。

因此我们知道,在默认情况下React中的函数会捕获props和state。但是如果我们想要读取并不属于这一次特定渲染的,最新的props和state呢?

在函数式组件中,你也可以拥有一个在所有的组件渲染帧中共享的可变变量。它被成为“ref”:

functionMyComponent(){constref=useRef(null);//你可以通过ref.current来获取保存的值.//...}在很多情况下,你并不需要它们,并且分配它们将是一种浪费。但是,如果你愿意,你可以这样手动地来追踪这些值:

functionMessageThread(){const[message,setMessage]=useState('');constlatestMessage=useRef('');constshowMessage=()=>{alert('Yousaid:'+latestMessage.current);};consthandleSendClick=()=>{setTimeout(showMessage,3000);};consthandleMessageChange=(e)=>{setMessage(e.target.value);latestMessage.current=e.target.value;};如果我们在state中读取,我们将得到在我们按下发送按钮那一刻的信息。但是当我们通过ref读取时,我们将得到最新的值,即使我们在按下发送按钮后继续输入。

通常情况下,你应该避免在渲染期间读取或者设置refs,因为它们是可变得。我们希望保持渲染的可预测性。然而,如果我们想要特定props或者state的最新值,那么手动更新ref会有些烦人。我们可以通过使用一个effect来自动化实现它:

functionMessageThread(){const[message,setMessage]=useState('');//保持追踪最新的值。constlatestMessage=useRef('');useEffect(()=>{latestMessage.current=message;});constshowMessage=()=>{alert('Yousaid:'+latestMessage.current);};正如我们上面看到的,闭包实际上帮我们解决了很难注意到的细微问题。同样,它们也使得在并发模式下能更轻松地编写能够正确运行的代码。这是可行的,因为组件内部的逻辑在渲染它时捕获并包含了正确的props和state。

React函数总是捕获他们的值——现在我们也知道这是为什么了。

THE END
1.类组件和函数式组件的区别类组件和函数组件区别在React的生态系统中,组件是构建用户界面的基本单元。React最初引入了类组件(Class Components)和函数式组件(Functional Components)两种组件类型。虽然这两种组件都可以实现相同的功能,但它们有各自的特点、优缺点和适用场景。本文将详细探讨类组件和函数式组件的区别,以及在实际开发中的应用。 https://blog.csdn.net/My_wife_QBL/article/details/140871717
2.react类组件和函数组件区别有哪些问答React 类组件和函数组件是两种不同的组件写法,它们之间有以下几个主要区别: 语法:React 类组件是通过 ES6 的 class 语法来定义的,而函数组件是通过函数来定义的。 写法:React 类组件需要继承 React.Component 类,并且使用 render() 方法来渲染组件的 JSX,而函数组件只需要直接返回 JSX 即可。 生命周期:React 类https://www.yisu.com/ask/2044141.html
3.React:函数组件与类有什么不同?函数组件捕获渲染的值。 让我们来解释下这意味着什么。 注意: 这篇文章不是对类或函数的价值判断。我只描述了React中这两种编程模型之间的区别。有关更广泛地采用功能的问题,请参阅Hooks FAQ。 考虑这个组件: functionProfilePage(props){constshowMessage=()=>{alert('Followed '+props.user);};consthandleClickhttps://www.jianshu.com/p/26926857ff73
4.前端面试知识题7.React2、hooks用过吗?聊聊react中class组件和函数组件的区别 类组件是使用ES6 的 class 来定义的组件。 函数组件是接收一个单一的 props 对象并返回一个React元素。 关于React的两套API(类(class)API 和基于函数的钩子(hooks) API)。官方推荐使用钩子(函数),而不是类。因为钩子更简洁,代码量少,用起来比较"轻",而https://developer.aliyun.com/article/1149037
5.聊聊函数式组件与类组件有何不同React 中最关键的知识点就是组件,在 React 16.8 之前(还没有 Hooks 前),我们的应用大多写成 Class 组件,因为 Class 组件有生命周期,能控制状态(state)。https://www.51cto.com/article/702921.html
6.一杯茶的时间,上手React框架开发我们还提出了组件的概念,但是并没有深入讲解它,在下一小节中我们将详细地讲解组件的知识。 Component React 的核心特点之一就是组件化,即我们将巨大的业务逻辑拆分成一个个逻辑清晰的小组件,然后通过组合这些组件来完成业务功能。 React 提供两种组件写法:1)函数式组件 2)类组件。 函数式组件 在React 中,函数https://www.imooc.com/article/298788
7.北京师范大学研究生院本课程重点培养编程思想和解决实际问题的能力。通过掌握Python语言的基本语法,利用Python的标准库和科学计算扩展库,解决数值、文本、图像等几类典型数据处理的实际问题;掌握程序设计的主要思想,养成良好的编程习惯,形成运用计算思维方法解决问题的能力,为进一步开展科学研究奠定基础。 http://ss.graduate.bnu.edu.cn/py/yzkc/detail?id=6267af01-f562-43f3-8c1e-f1dd062a233d
8.轻松学会React钩子:以useEffect()为例二、类和函数的差异 严格地说,类组件和函数组件是有差异的。不同的写法,代表了不同的编程方法论。 类(class)是数据和逻辑的封装。也就是说,组件的状态和操作方法是封装在一起的。如果选择了类的写法,就应该把相关的数据和操作,都写在同一个 class 里面。 http://www.ruanyifeng.com/blog/2020/09/react-hooks-useeffect-tutorial.html