当前位置: 首页 > 科技观察

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

时间:2023-03-22 01:36:32 科技观察

先说功能组件和类组件的区别,可以控制状态(state)。而功能组件只能默默的站在后面,说自己是puppet组件(也就是所谓的无状态组件),传递props,展示UI。下面的文字是根据Hooks后的文字功能组件和类组件是否有根本的区别?功能组件在渲染时捕获值。详见这篇文章:函数式组件与类组件有何不同?因为props在React中是不可变的,所以它们永远不会改变。然而,这是可变的这一事实是它的类组件。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指向最新的值。类组件要保存原值怎么办?1.调用事件前阅读this.props。可以看到网上的DemoshowMessage=(value)=>{alert("最新值为"+value);};handleClick=()=>{const{value}=this.state;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对象是一个具有当前属性的容器。在最后一个例子中,我们可以使用函数式组件这样写: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
);};可以看在线Demo。这里作者提出两个问题:为什么ref可以保存最新的值?为什么函数式组件可以捕获它,而类组件不能?