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