当前位置: 首页 > Web前端 > JavaScript

函数式组件与类组件有何不同

时间:2023-03-26 22:57:36 JavaScript

功能组件和类组件的区别控制状态(state)。而功能组件只能默默的站在后面,说自己是puppet组件(也就是所谓的无状态组件),传递props,展示UI。下面的文字是基于Hooks之后的文字功能组件和类组件有没有根本的区别?函数式组件捕捉渲染的价值可以参考这篇文章:函数式组件和类组件有什么区别?因为props在React中是不可变的,所以它们永远不会改变。然而,this可变的事实是this存在的类组件。React本身会随着时间的推移而变化,因此您可以在渲染方法和生命周期方法中获取最新的实例。功能组件捕获当前状态下的值。如果使用计时器改变当前值的状态,函数公式组件仍然显示旧值而不是最新值。类组件总是在渲染后立即获得最新值,而功能组件将捕获当前值。即使类组件被渲染了,它的this也会指向最新的实例类组件。可以看网上DemoclassClassDemoextendsReact.Component{state={value:""};showMessage=()=>{alert("最新值"+this.state.value);};handleMessageChange=(e)=>{this.setState({value:e.target.value});};handleClick=()=>{setTimeout(this.showMessage,3000);};render(){return(

Click
);}}这样的结果是得到点击后的最新值,不是3秒前的值。为什么?因为this是可变的,3秒后执行alert("Thelatestvalueis"+this.state.value)。this.state.value指向最新的值。如果class组件想保存原来的值怎么办?1、调用事件前读this.props,可以看到网上的DemoshowMessage=(value)=>{alert("Thelatestvalueis"+value);};handleClick=()=>{const{value}=这个.状态;setTimeout(()=>this.showMessage(value),3000);};可以解决,但是点击的时候获取的是当前用户,然后传给this.showMessage,这样3秒后还是原来的值缺点:每次都要从this.props中获取值,数据太多,写起来不人性化。2.可以看网上的Democonstructor(props){super(props);this.showMessage=this在构造函数中绑定的方法.showMessage.bind(this);this.handleClick=this.handleClick.bind(this);}这个方法没有解决问题。我们的问题是我们从this.props读取数据的时间太晚了——它不是我们读取时需要使用的上下文。3.使用closure把方法写到render里面,这样每次渲染的时候都可以捕获当时用到的props或者state,网上可以看DemoclassClassDemoextendsReact.Component{state={value:""};render(){const{value}=this.state;constshowMessage=()=>{alert("最新值为"+value);};consthandleMessageChange=(e)=>{this.setState({value:e.target.value});};consthandleClick=()=>{setTimeout(showMessage,3000);};返回(
click
);}}但是这种方法很笨,这种写法和函数式组件有什么区别呢?为什么不使用功能组件?如果功能组件要保存最新值,使用useRef保存最新值,让组件获取最新值。functionMyComponent(){constref=useRef(null);}首先,ref和instance扮演着同样的角色,ref对象是一个容器,有一个current属性。在最后一个例子中,我们可以使用函数式组件这样写:constFunctionDemo=()=>{const[value,setValue]=useState("");constrefValue=useRef("");constshowMessage=()=>{alert("最新值为"+refValue.current);};常量handleMessageChange=(e)=>{setValue(e.target.value);refValue.current=e.target.value;};consthandleClick=()=>{setTimeout(showMessage,3000);};return(
Click
);};你可以看在线演示。这里作者提出两个问题:为什么ref可以保存最新的值?为什么函数式组件捕获类组件而不捕获类组件?后续文章将给出笔者的答案。参考资料功能组件和类组件有什么区别?