摘要:而主要被設(shè)計(jì)用于維持組件內(nèi)部私有狀態(tài)。初始化初始化需要在中進(jìn)行。對(duì)于的定義為請(qǐng)求修改某個(gè)數(shù)據(jù),而的實(shí)現(xiàn)則是將對(duì)變量的修改放入一個(gè)修改隊(duì)列中,在一個(gè)循環(huán)之后進(jìn)行批量更新結(jié)果深入點(diǎn)涉及的更新機(jī)制。推出了與版本之后推出來(lái)的就是為了解決這些問(wèn)題的。
3.1 什么是state
我們要認(rèn)識(shí)到,React中的組件其實(shí)是一個(gè)函數(shù),所以state是函數(shù)內(nèi)部的私有變量,外部其他組件或者方法都是無(wú)法直接訪問(wèn)到內(nèi)部的state。
而state主要被設(shè)計(jì)用于維持組件內(nèi)部私有狀態(tài)。
初始化state需要在class中constructor進(jìn)行。
import React, { PureComponent } from "react" export default class index extends PureComponent { constructor(props){ super(props) this.state = {name:"demo react",time:new Date()} } render() { return (Hello world React!{this.state.name}) } }組件生成時(shí)間:{this.state.time}
在這個(gè)代碼中,我們初始化了name,time兩個(gè)state值。一旦state初始化完成,我們就可以在render中進(jìn)行訪問(wèn)。
使用npm run dev命令運(yùn)行,并在瀏覽器中打開(kāi)查看吧。
我們已經(jīng)知道了如何初始化組件中的state值,那么接下來(lái)我們來(lái)看看,如何實(shí)現(xiàn)修改state的值
import React, { PureComponent } from "react" export default class index extends PureComponent { constructor(props){ super(props) this.state = {name:"demo react",time:+new Date()} } handleUpdateName () { this.state.time = (+new Date()) } render() { return (Hello world React!{this.state.name}) } }組件生成時(shí)間:{this.state.time}
有些動(dòng)作快的同學(xué),第一個(gè)想法就是如此修改組件中的state值,但是值得玩味的是,值的確是修改成功了,但是,并沒(méi)有實(shí)時(shí)體現(xiàn)在界面上。這究竟是怎么回事呢?
這就要來(lái)看看,React中的setState方法。
React對(duì)于setState的定義為請(qǐng)求React修改某個(gè)數(shù)據(jù),而React的實(shí)現(xiàn)則是將對(duì)變量的修改放入一個(gè)修改隊(duì)列中,在一個(gè)循環(huán)之后進(jìn)行批量更新結(jié)果(深入點(diǎn)涉及VDom的更新機(jī)制)。所以,這里會(huì)造成一個(gè)問(wèn)題,就是setState數(shù)據(jù)之后立刻進(jìn)行讀取,可能你讀取到的數(shù)據(jù),并非是已經(jīng)被更新過(guò)的有效值。
setState有三種修改數(shù)據(jù)的方式,讓我們來(lái)一個(gè)一個(gè)嘗試。
import React, { PureComponent } from "react" export default class index extends PureComponent { constructor(props){ super(props) this.state = {name:"demo react",time:+new Date()} } handleUpdateName () { // this.state.time = (+new Date()) console.log("修改前的值",this.state.time) this.setState({time:+new Date()}) console.log("修改后的值",this.state.time) let that = this setTimeout(function(){ console.log("當(dāng)前state值",that.state.time) }) } render() { return (Hello world React!{this.state.name}) } }組件生成時(shí)間:{this.state.time}
點(diǎn)擊按鈕,控制臺(tái)輸出了不同的值,可以觀察到setState是采用異步隊(duì)列模式的。
現(xiàn)在出現(xiàn)了一個(gè)問(wèn)題,如果我們需要通過(guò)等待setState修改完成的值之后,應(yīng)該如何處理?React為我們的setState提供了第二個(gè)參數(shù)callback。
import React, { PureComponent } from "react" export default class index extends PureComponent { constructor(props){ super(props) this.state = {name:"demo react",time:+new Date()} } handleUpdateName () { // this.state.time = (+new Date()) console.log("修改前的值",this.state.time) this.setState({time:+new Date()},(function(){ console.log("當(dāng)前state值",that.state.time) }) console.log("修改后的值",this.state.time) } render() { return (Hello world React!{this.state.name}) } }組件生成時(shí)間:{this.state.time}
再次運(yùn)行,并且點(diǎn)擊按鈕。我們可以看到控制臺(tái)輸出的值是跟第一個(gè)方法是一致的。
現(xiàn)在我們來(lái)進(jìn)行一次腦暴,可不可以直接修改state值呢?因?yàn)槲覀冊(cè)谧钤缰苯訉?duì)state修改的時(shí)候,React并未關(guān)閉這個(gè)對(duì)象的set方法。那么我們可否直接通過(guò)修改state來(lái)進(jìn)行渲染呢?React中的一個(gè)方法為我們解決了這個(gè)疑問(wèn)。
import React, { PureComponent } from "react" export default class index extends PureComponent { constructor(props){ super(props) this.state = {name:"demo react",time:+new Date()} } handleUpdateName () { console.log("修改前的值", this.state.time); this.state.time = (+new Date()) console.log("修改后的值", this.state.time); console.log("當(dāng)前state值", this.state.time); this.forceUpdate() } render() { return (Hello world React!{this.state.name}) } }組件生成時(shí)間:{this.state.time}
上面這個(gè)代碼僅僅用于腦暴,參考,不要在生產(chǎn)環(huán)境中使用,因?yàn)檫@個(gè)會(huì)造成React渲染算法與各種Hook失效,造成全局重新渲染。
在某些場(chǎng)景下面,我們可能是新的值是基于上一次的值推算而來(lái),所以React提供了setState傳遞進(jìn)方法來(lái)進(jìn)行推算處理。
import React, { PureComponent } from "react"; export default class index extends PureComponent { constructor(props) { super(props); this.state = { name: "demo react", time: +new Date() }; } handleUpdateName() { console.log("修改前的值", this.state.time); let that = this; this.setState(oldData => { return { time: oldData.time + 1000 }; }); console.log("修改后的值", this.state.time); setTimeout(function() { console.log("當(dāng)前state值", that.state.time); }); } render() { return (Hello world React!{this.state.name}); } }組件生成時(shí)間:{this.state.time}
最后說(shuō)一點(diǎn),就是setState是淺拷貝,如果是結(jié)構(gòu)比較深層的對(duì)象,很多同學(xué)會(huì)采用JSON.string()這種來(lái)進(jìn)行深拷貝,這樣的操作雖然說(shuō)是可以的,但是非常影響性能。
React推出了immutable與15版本之后推出來(lái)的PureComponent就是為了解決這些問(wèn)題的。有興趣的同學(xué)可以搜索一下相關(guān)資料進(jìn)行拓展閱讀。
3.2 什么是props我們知道,在函數(shù)中有帶參數(shù)的方法,那么props其實(shí)就是傳入方法中的參數(shù)。并且在React中props是只讀屬性。在使用場(chǎng)景上,是由父組件向子組件傳遞值的時(shí)候使用的。
我們首先創(chuàng)建一個(gè)可以接收props值的組件。
import React, { PureComponent } from "react"; export default class index extends PureComponent { constructor(props) { super(props); } render() { return ({this.props.value||"暫無(wú)數(shù)據(jù)"}); } }
接著,我們修改Index.js引用這個(gè)組件。
import React, { PureComponent } from "react"; import Content from "./content.js" export default class index extends PureComponent { constructor(props) { super(props); this.state = { name: "demo react", time: +new Date() }; } handleUpdateName() { this.setState({time:+new Date()}) } render() { return (Hello world React!{this.state.name}); } }組件生成時(shí)間:{this.state.time}
這里大家有一點(diǎn)要注意,在React中,所有的組件名稱(chēng)第一個(gè)字母都必須大寫(xiě),這是為了與html標(biāo)簽區(qū)分出來(lái)。
如何向子組件傳值呢?就像給html標(biāo)簽增加屬性一樣。
這樣,組件內(nèi)部可以通過(guò)props讀取到value值了。不過(guò)React的組件傳遞中有一個(gè)很有趣的屬性children,這個(gè)的用處傳遞組件包含的內(nèi)容。
繼續(xù)修改引入組件的代碼,如下
// index.js主體Children
import React, { PureComponent } from "react"; export default class index extends PureComponent { constructor(props) { super(props); } render() { return ({this.props.value||"暫無(wú)數(shù)據(jù)"},children:{this.props.children}); } }
最終顯示效果就是這樣的
原文地址:https://www.yodfz.com/detail/...
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/100908.html
摘要:原文地址是一個(gè)庫(kù),主要是通過(guò)操作數(shù)據(jù)的方式去操縱,為什么要重造輪子呢,因?yàn)橛X(jué)的目前市面上的框架對(duì)于創(chuàng)建大型應(yīng)用程序不夠直觀,不能滿(mǎn)足需求,所以誕生了。其實(shí)說(shuō)它性能高,只不過(guò)是用的方式計(jì)算出最小的操作,所以性能就上來(lái)了。 原文地址:https://gmiam.com/post/react-... React 是一個(gè) JS 庫(kù),主要是通過(guò)操作數(shù)據(jù)的方式去操縱 DOM,為什么要重造輪子呢,因...
摘要:本篇講解雙源屬性不可變數(shù)據(jù)事件驅(qū)動(dòng)等??杀粋陕?tīng),被偵聽(tīng)后源頭若發(fā)生變化,相應(yīng)的偵聽(tīng)函數(shù)將自動(dòng)被調(diào)起。本文完本專(zhuān)欄歷史文章介紹一項(xiàng)讓可以與抗衡的技術(shù)可視化開(kāi)發(fā)工具非正經(jīng)入門(mén)之一三宗罪可視化開(kāi)發(fā)工具非正經(jīng)入門(mén)之二分離界面設(shè)計(jì) 本系列博文從 Shadow Widget 作者的視角,解釋該框架的設(shè)計(jì)要點(diǎn)。本篇講解雙源屬性、不可變數(shù)據(jù)、事件驅(qū)動(dòng)等。 showImg(https://segment...
摘要:在構(gòu)造函數(shù)里面初始化的數(shù)據(jù),把數(shù)據(jù)放在頁(yè)面上,點(diǎn)擊時(shí)候調(diào)用方法改變中的數(shù)據(jù)。是中父組件向子組件通信的方式,下面是一個(gè)簡(jiǎn)單的例子使用組件我是顯示的數(shù)據(jù)我們定義組件時(shí)候在構(gòu)造函數(shù)中可以接收到參數(shù),并且要使用傳到的構(gòu)造方法中。 React的學(xué)習(xí)之路還要繼續(xù)走下去,最近一邊在做未完成的項(xiàng)目一邊學(xué)習(xí)React,項(xiàng)目是vue寫(xiě)的,后面還需要有一個(gè)后臺(tái)管理系統(tǒng)計(jì)劃使用react完成,寒假說(shuō)長(zhǎng)也不長(zhǎng),...
摘要:讓他增加一個(gè)內(nèi)部維持的狀態(tài)另外有一點(diǎn)需要注意,由于是無(wú)狀態(tài)組件,所以,無(wú)論是否變更,都會(huì)重新刷新這個(gè)組件。 4.1 什么是無(wú)狀態(tài)組件 在開(kāi)發(fā)React組件的時(shí)候,大家可能會(huì)遇到就是我使用的這個(gè)組件純粹就是渲染使用,里面并沒(méi)有自己的狀態(tài)、方法、生命周期等等操作。 而為這種組件創(chuàng)建完整的實(shí)例有一種浪費(fèi)機(jī)器性能的感覺(jué)。 那么,讓我們來(lái)看看,如何創(chuàng)建一個(gè)easy react component...
0x000 概述 上一章說(shuō)明了生命周期的概念,本質(zhì)上就是框架在操作組件的過(guò)程中暴露出來(lái)的一系列鉤子,我們可以選擇我們需要的鉤子,完成我們自己的業(yè)務(wù),以下講的是react v16.3以下的生命周期,v16.3以及以上的版本有所不同 0x001 組件掛載 以下是組件掛載的過(guò)程中觸發(fā)的聲明周期: class App extends React.Component { constructor(pr...
閱讀 3486·2023-04-26 02:48
閱讀 1475·2021-10-11 10:57
閱讀 2502·2021-09-23 11:35
閱讀 1210·2021-09-06 15:02
閱讀 3310·2019-08-30 15:54
閱讀 1626·2019-08-30 15:44
閱讀 893·2019-08-30 15:44
閱讀 1000·2019-08-30 12:52