一区二区三区三上|欧美在线视频五区|国产午夜无码在线观看视频|亚洲国产裸体网站|无码成年人影视|亚洲AV亚洲AV|成人开心激情五月|欧美性爱内射视频|超碰人人干人人上|一区二区无码三区亚洲人区久久精品

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內(nèi)不再提示

React重新渲染指的是什么

OSC開源社區(qū) ? 來源:阿里巴巴終端技術 ? 作者:梁瑞鋒(曉玉) ? 2022-11-23 09:59 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

緣起

React 重新渲染,指的是在類函數(shù)中,會重新執(zhí)行 render 函數(shù),類似 Flutter 中的 build 函數(shù),函數(shù)組件中,會重新執(zhí)行這個函數(shù)

React 組件在組件的狀態(tài) state 或者組件的屬性 props 改變的時候,會重新渲染,條件簡單,但是實際上稍不注意,會引起災難性的重新渲染

類組件

為什么拿類組件先說,怎么說呢,更好理解?還有前幾年比較流行的一些常見面試題

React 中的 setState 什么時候是同步的,什么時候是異步的

React setState 怎么獲取最新的 state

以下代碼的輸出值是什么,頁面展示是怎么變化的

test=()=>{
//s1=1
const{s1}=this.state;
this.setState({s1:s1+1});
this.setState({s1:s1+1});
this.setState({s1:s1+1});
console.log(s1)
};

render(){
return(
按鈕
{this.state.s1}
); }

看到這些類型的面試問題,熟悉 React 事務機制的你一定能答出來,畢竟不難嘛,哈?你不知道 React 的事務機制?百度|谷歌|360|搜狗|必應 React 事務機制

React 合成事件

在 React 組件觸發(fā)的事件會被冒泡到 document(在 react v17 中是 react 掛載的節(jié)點,例如 document.querySelector('#app')),然后 React 按照觸發(fā)路徑上收集事件回調(diào),分發(fā)事件。

這里是不是突發(fā)奇想,如果禁用了,在觸發(fā)事件的節(jié)點,通過原生事件禁止事件冒泡,是不是 React 事件就沒法觸發(fā)了?確實是這樣,沒法冒泡了,React 都沒法收集事件和分發(fā)事件了,注意這個冒泡不是 React 合成事件的冒泡。

發(fā)散一下還能想到的另外一個點,React ,就算是在合成捕獲階段觸發(fā)的事件,依舊在原生冒泡事件觸發(fā)之后

reactEventCallback=()=>{
//s1s2s3都是1
const{s1,s2,s3}=this.state;
this.setState({s1:s1+1});
this.setState({s2:s2+1});
this.setState({s3:s3+1});
console.log('aftersetStates1:',this.state.s1);
//這里依舊輸出1,頁面展示2,頁面僅重新渲染一次
};


S1:{s1}S2:{s2}S3:{s3}

定時器回調(diào)后觸發(fā) setState

定時器回調(diào)執(zhí)行 setState 是同步的,可以在執(zhí)行 setState 之后直接獲取,最新的值,例如下面代碼

timerCallback=()=>{
setTimeout(()=>{
//s1s2s3都是1
const{s1,s2,s3}=this.state;
this.setState({s1:s1+1});
console.log('aftersetStates1:',this.state.s1);
//輸出2頁面渲染3次
this.setState({s2:s2+1});
this.setState({s3:s3+1});
});
};

異步函數(shù)后調(diào)觸發(fā) setState

異步函數(shù)回調(diào)執(zhí)行 setState 是同步的,可以在執(zhí)行 setState 之后直接獲取,最新的值,例如下面代碼

asyncCallback=()=>{
Promise.resolve().then(()=>{
//s1s2s3都是1
const{s1,s2,s3}=this.state;
this.setState({s1:s1+1});
console.log('aftersetStates1:',this.state.s1);
//輸出2頁面渲染3次
this.setState({s2:s2+1});
this.setState({s3:s3+1});
});
};

原生事件觸發(fā)

原生事件同樣不受 React 事務機制影響,所以 setState 表現(xiàn)也是同步的

componentDidMount(){
constbtn1=document.getElementById('native-event');
btn1?.addEventListener('click',this.nativeCallback);
}

nativeCallback=()=>{
//s1s2s3都是1
const{s1,s2,s3}=this.state;
this.setState({s1:s1+1});
console.log('aftersetStates1:',this.state.s1);
//輸出2頁面渲染3次
this.setState({s2:s2+1});
this.setState({s3:s3+1});
};


NativeEvent

setState 修改不參與渲染的屬性

setState 調(diào)用就會引起就會組件重新渲染,即使這個狀態(tài)沒有參與頁面渲染,所以,請不要把非渲染屬性放 state 里面,即使放了 state,也請不要通過 setState 去修改這個狀態(tài),直接調(diào)用 this.state.xxx = xxx 就好,這種不參與渲染的屬性,直接掛在 this 上就好,參考下圖

//s1s2s3為渲染的屬性,s4非渲染屬性
state={
s1:1,
s2:1,
s3:1,
s4:1,
};

s5=1;

changeNotUsedState=()=>{
const{s4}=this.state;
this.setState({s4:s4+1});
//頁面會重新渲染

//頁面不會重新渲染
this.state.s4=2;
this.s5=2;
};

S1:{s1}S2:{s2}S3:{s3}
;

只是調(diào)用 setState,頁面會不會重新渲染

幾種情況,分別是:

直接調(diào)用 setState,無參數(shù)

setState,新 state 和老 state 完全一致,也就是同樣的 state

sameState=()=>{
const{s1}=this.state;
this.setState({s1});
//頁面會重新渲染
};

noParams=()=>{
this.setState({});
//頁面會重新渲染
};

這兩種情況,處理起來和普通的修改狀態(tài)的 setState 一致,都會引起重新渲染的

多次渲染的問題

為什么要提上面這些,仔細看,這里提到了很多次渲染的 3 次,比較契合我們?nèi)粘懘a的,異步函數(shù)回調(diào),畢竟在定時器回調(diào)或者給組件綁定原生事件(沒事找事是吧?),挺少這么做的吧,但是異步回調(diào)就很多了,比如網(wǎng)絡請求啥的,改變個 state 還是挺常見的,但是渲染多次,就是不行!不過利用 setState 實際上是傳一個新對象合并機制,可以把變化的屬性合并在新的對象里面,一次性提交全部變更,就不用調(diào)用多次 setState 了

asyncCallbackMerge=()=>{
Promise.resolve().then(()=>{
const{s1,s2,s3}=this.state;
this.setState({s1:s1+1,s2:s2+1,s3:s3+1});
console.log('aftersetStates1:',this.state.s1);
//輸出2頁面渲染1次
});
};

這樣就可以在非 React 的事務流中避開多次渲染的問題

測試代碼

importReactfrom'react';

interfaceState{
s1:number;
s2:number;
s3:number;
s4:number;
}

//eslint-disable-next-line@iceworks/best-practices/recommend-functional-component
exportdefaultclassTestClassextendsReact.Component{
renderTime:number;
constructor(props:any){
super(props);
this.renderTime=0;
this.state={
s1:1,
s2:1,
s3:1,
s4:1,
};
}

componentDidMount(){
constbtn1=document.getElementById('native-event');
constbtn2=document.getElementById('native-event-async');
btn1?.addEventListener('click',this.nativeCallback);
btn2?.addEventListener('click',this.nativeCallbackMerge);
}

changeNotUsedState=()=>{
const{s4}=this.state;
this.setState({s4:s4+1});
};

reactEventCallback=()=>{
const{s1,s2,s3}=this.state;
this.setState({s1:s1+1});
this.setState({s2:s2+1});
this.setState({s3:s3+1});
console.log('aftersetStates1:',this.state.s1);
};
timerCallback=()=>{
setTimeout(()=>{
const{s1,s2,s3}=this.state;
this.setState({s1:s1+1});
console.log('aftersetStates1:',this.state.s1);
this.setState({s2:s2+1});
this.setState({s3:s3+1});
});
};
asyncCallback=()=>{
Promise.resolve().then(()=>{
const{s1,s2,s3}=this.state;
this.setState({s1:s1+1});
console.log('aftersetStates1:',this.state.s1);
this.setState({s2:s2+1});
this.setState({s3:s3+1});
});
};
nativeCallback=()=>{
const{s1,s2,s3}=this.state;
this.setState({s1:s1+1});
console.log('aftersetStates1:',this.state.s1);
this.setState({s2:s2+1});
this.setState({s3:s3+1});
};
timerCallbackMerge=()=>{
setTimeout(()=>{
const{s1,s2,s3}=this.state;
this.setState({s1:s1+1,s2:s2+1,s3:s3+1});
console.log('aftersetStates1:',this.state.s1);
});
};
asyncCallbackMerge=()=>{
Promise.resolve().then(()=>{
const{s1,s2,s3}=this.state;
this.setState({s1:s1+1,s2:s2+1,s3:s3+1});
console.log('aftersetStates1:',this.state.s1);
});
};
nativeCallbackMerge=()=>{
const{s1,s2,s3}=this.state;
this.setState({s1:s1+1,s2:s2+1,s3:s3+1});
console.log('aftersetStates1:',this.state.s1);
};
sameState=()=>{
const{s1,s2,s3}=this.state;
this.setState({s1});
this.setState({s2});
this.setState({s3});
console.log('aftersetStates1:',this.state.s1);
};
withoutParams=()=>{
this.setState({});
};

render(){
console.log('renderTime',++this.renderTime);
const{s1,s2,s3}=this.state;
return(

ReactEvent
TimerCallback
AsyncCallback
NativeEvent
TimerCallbackMerge
AsyncCallbackMerge
NativeEventMerge
ChangeNotUsedState
ReactEventSetSameState

ReactEventSetStateWithoutParams

S1:{s1}S2:{s2}S3:{s3}
); } }

函數(shù)組件

函數(shù)組件重新渲染的條件也和類組件一樣,組件的屬性 Props 和組件的狀態(tài) State 有修改的時候,會觸發(fā)組件重新渲染,所以類組件存在的問題,函數(shù)組件同樣也存在,而且因為函數(shù)組件的 state 不是一個對象,情況就更糟糕

React 合成事件

constreactEventCallback=()=>{
//S1S2S3都是1
setS1((i)=>i+1);
setS2((i)=>i+1);
setS3((i)=>i+1);
//頁面只會渲染一次,S1S2S3都是2
};

定時器回調(diào)

consttimerCallback=()=>{
setTimeout(()=>{
//S1S2S3都是1
setS1((i)=>i+1);
setS2((i)=>i+1);
setS3((i)=>i+1);
//頁面只會渲染三次,S1S2S3都是2
});
};

異步函數(shù)回調(diào)

constasyncCallback=()=>{
Promise.resolve().then(()=>{
//S1S2S3都是1
setS1((i)=>i+1);
setS2((i)=>i+1);
setS3((i)=>i+1);
//頁面只會渲染三次,S1S2S3都是2
});
};

原生事件

useEffect(()=>{
consthandler=()=>{
//S1S2S3都是1
setS1((i)=>i+1);
setS2((i)=>i+1);
setS3((i)=>i+1);
//頁面只會渲染三次,S1S2S3都是2
};
containerRef.current?.addEventListener('click',handler);
return()=>containerRef.current?.removeEventListener('click',handler);
},[]);

更新沒使用的狀態(tài)

const[s4,setS4]=useState(1);
constunuseState=()=>{
setS4((s)=>s+1);
//s4===2頁面渲染一次S4頁面上沒用到
};

總結

以上的全部情況,在 React Hook 中表現(xiàn)的情況和類組件表現(xiàn)完全一致,沒有任何差別,但是也有表現(xiàn)不一致的地方

不同的情況 設置同樣的 State

在 React Hook 中設置同樣的 State,并不會引起重新渲染,這點和類組件不一樣,但是這個不一定的,引用 React 官方文檔說法

如果你更新 State Hook 后的 state 與當前的 state 相同時,React 將跳過子組件的渲染并且不會觸發(fā) effect 的執(zhí)行。(React 使用 Object.is 比較算法 來比較 state。)

需要注意的是,React 可能仍需要在跳過渲染前渲染該組件。不過由于 React 不會對組件樹的“深層”節(jié)點進行不必要的渲染,所以大可不必擔心。如果你在渲染期間執(zhí)行了高開銷的計算,則可以使用 useMemo 來進行優(yōu)化。

官方穩(wěn)定有提到,新舊 State 淺比較完全一致是不會重新渲染的,但是有可能還是會導致重新渲染

//ReactHook
constsameState=()=>{
setS1((i)=>i);
setS2((i)=>i);
setS3((i)=>i);
console.log(renderTimeRef.current);
//頁面并不會重新渲染
};

//類組件中
sameState=()=>{
const{s1,s2,s3}=this.state;
this.setState({s1});
this.setState({s2});
this.setState({s3});
console.log('aftersetStates1:',this.state.s1);
//頁面會重新渲染
};

這個特性存在,有些時候想要獲取最新的 state,又不想給某個函數(shù)添加 state 依賴或者給 state 添加一個 useRef,可以通過這個函數(shù)去或者這個 state 的最新值

constsameState=()=>{
setS1((i)=>{
constlatestS1=i;
//latestS1是當前S1最新的值,可以在這里處理一些和S1相關的邏輯
returnlatestS1;
});
};

React Hook 中避免多次渲染

React Hook 中 state 并不是一個對象,所以不會自動合并更新對象,那怎么解決這個異步函數(shù)之后多次 setState 重新渲染的問題?

將全部 state 合并成一個對象

const[state,setState]=useState({s1:1,s2:1,s3:1});
setState((prevState)=>{
setTimeout(()=>{
const{s1,s2,s3}=prevState;
return{...prevState,s1:s1+1,s2:s2+1,s3:s3+1};
});
});

參考類的的 this.state 是個對象的方法,把全部的 state 合并在一個組件里面,然后需要更新某個屬性的時候,直接調(diào)用 setState 即可,和類組件的操作完全一致,這是一種方案

使用 useReducer

雖然這個 hook 的存在感確實低,但是多狀態(tài)的組件用這個來替代 useState 確實不錯

constinitialState={s1:1,s2:1,s3:1};

functionreducer(state,action){
switch(action.type){
case'update':
return{s1:state.s1+1,s2:state.s2+1,s3:state.s3+1};
default:
returnstate;
}
}

const[reducerState,dispatch]=useReducer(reducer,initialState);
constreducerDispatch=()=>{
setTimeout(()=>{
dispatch({type:'update'});
});
};

具體的用法不展開了,用起來和 redux 差別不大

狀態(tài)直接用 Ref 聲明,需要更新的時候調(diào)用更新的函數(shù)(不推薦)

//S4不參與渲染
const[s4,setS4]=useState(1);
//update就是useReducer的dispatch,調(diào)用就更更新頁面,比定義一個不渲染的state好多了
const[,update]=useReducer((c)=>c+1,0);
conststate1Ref=useRef(1);
conststate2Ref=useRef(1);

constunRefSetState=()=>{
//優(yōu)先更新ref的值
state1Ref.current+=1;
state2Ref.current+=1;
setS4((i)=>i+1);
};

constunRefSetState=()=>{
//優(yōu)先更新ref的值
state1Ref.current+=1;
state2Ref.current+=1;
update();
};

state1Ref:{state1Ref.current}state2Ref:{state2Ref.current}
;

這樣做,把真正渲染的 state 放到了 ref 里面,這樣有個好處,就是函數(shù)里面不用聲明這個 state 的依賴了,但是壞處非常多,更新的時候必須說動調(diào)用 update,同時把 ref 用來渲染也比較奇怪

自定義 Hook

自定義 Hook 如果在組件中使用,任何自定義 Hook 中的狀態(tài)改變,都會引起組件重新渲染,包括組件中沒用到的,但是定義在自定義 Hook 中的狀態(tài)

簡單的例子,下面的自定義 hook,有 id 和 data 兩個狀態(tài), id 甚至都沒有導出,但是 id 改變的時候,還是會導致引用這個 Hook 的組件重新渲染

//一個簡單的自定義Hook,用來請求數(shù)據(jù)
constuseDate=()=>{
const[id,setid]=useState(0);
const[data,setData]=useState(null);

useEffect(()=>{
fetch('請求數(shù)據(jù)的URL')
.then((r)=>r.json())
.then((r)=>{
//組件重新渲染
setid((i)=>i+1);
//組件再次重新渲染
setData(r);
});
},[]);

returndata;
};

//在組件中使用,即使只導出了data,但是id變化,同時也會導致組件重新渲染,所以組件在獲取到數(shù)據(jù)的時候,組件會重新渲染兩次
constdata=useDate();

測試代碼

//use-data.ts
constuseDate=()=>{
const[id,setid]=useState(0);
const[data,setData]=useState(null);

useEffect(()=>{
fetch('數(shù)據(jù)請求地址')
.then((r)=>r.json())
.then((r)=>{
setid((i)=>i+1);
setData(r);
});
},[]);

returndata;
};

import{useEffect,useReducer,useRef,useState}from'react';
importuseDatefrom'./use-data';

constinitialState={s1:1,s2:1,s3:1};

functionreducer(state,action){
switch(action.type){
case'update':
return{s1:state.s1+1,s2:state.s2+1,s3:state.s3+1};
default:
returnstate;
}
}

constTestHook=()=>{
constrenderTimeRef=useRef(0);
const[s1,setS1]=useState(1);
const[s2,setS2]=useState(1);
const[s3,setS3]=useState(1);
const[s4,setS4]=useState(1);
const[,update]=useReducer((c)=>c+1,0);
conststate1Ref=useRef(1);
conststate2Ref=useRef(1);
constdata=useDate();
const[state,setState]=useState({s1:1,s2:1,s3:1});
const[reducerState,dispatch]=useReducer(reducer,initialState);
constcontainerRef=useRef(null);

constreactEventCallback=()=>{
setS1((i)=>i+1);
setS2((i)=>i+1);
setS3((i)=>i+1);
};

consttimerCallback=()=>{
setTimeout(()=>{
setS1((i)=>i+1);
setS2((i)=>i+1);
setS3((i)=>i+1);
});
};

constasyncCallback=()=>{
Promise.resolve().then(()=>{
setS1((i)=>i+1);
setS2((i)=>i+1);
setS3((i)=>i+1);
});
};

constunuseState=()=>{
setS4((i)=>i+1);
};

constunRefSetState=()=>{
state1Ref.current+=1;
state2Ref.current+=1;
setS4((i)=>i+1);
};

constunRefReducer=()=>{
state1Ref.current+=1;
state2Ref.current+=1;
update();
};

constsameState=()=>{
setS1((i)=>i);
setS2((i)=>i);
setS3((i)=>i);
console.log(renderTimeRef.current);
};

constmergeObjectSetState=()=>{
setTimeout(()=>{
setState((prevState)=>{
const{s1:prevS1,s2:prevS2,s3:prevS3}=prevState;
return{...prevState,s1:prevS1+1,s2:prevS2+1,s3:prevS3+1};
});
});
};

constreducerDispatch=()=>{
setTimeout(()=>{
dispatch({type:'update'});
});
};

useEffect(()=>{
consthandler=()=>{
setS1((i)=>i+1);
setS2((i)=>i+1);
setS3((i)=>i+1);
};
containerRef.current?.addEventListener('click',handler);
return()=>containerRef.current?.removeEventListener('click',handler);
},[]);

console.log('renderTimeHook',++renderTimeRef.current);
console.log('data',data);
return(

ReactEvent
TimerCallback
AsyncCallback

NativeEvent

UnuseState
SameState
MergeStateIntoanObject
ReducerDispatch
useRefAsStateWithuseState
useRefAsStateWithuseReducer
S1:{s1}S2:{s2}S3:{s3}
MergeObjectS1:{state.s1}S2:{state.s2}S3:{state.s3}
reducerStateObjectS1:{reducerState.s1}S2:{reducerState.s2}S3:{''} {reducerState.s3}
state1Ref:{state1Ref.current}state2Ref:{state2Ref.current}
); }; exportdefaultTestHook;

規(guī)則記不住怎么辦?

上面羅列了一大堆情況,但是這些規(guī)則難免會記不住,React 事務機制導致的兩種完全截然不然的重新渲染機制,確實讓人覺得有點惡心,React 官方也注意到了,既然在事務流的中 setState 可以合并,那不在 React 事務流的回調(diào),能不能也合并,答案是可以的,React 官方其實在 React V18 中, setState 能做到合并,即使在異步回調(diào)或者定時器回調(diào)或者原生事件綁定中,可以把測試代碼直接丟 React V18 的環(huán)境中嘗試,就算是上面列出的會多次渲染的場景,也不會重新渲染多次

但是,有了 React V18 最好也記錄一下以上的規(guī)則,對于減少渲染次數(shù)還是很有幫助的





審核編輯:劉清

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴

原文標題:React中的重新渲染

文章出處:【微信號:OSC開源社區(qū),微信公眾號:OSC開源社區(qū)】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    用WEB技術棧開發(fā)NATIVE應用(二):WEEX 前端SDK原理詳解

    、createElement 、appendChild 這三個接口,簡單構建了一個用于渲染的節(jié)點樹,最終生成了兩條渲染指令。Platform API 指的是原生環(huán)境提供的 API,這些 API 是 Weex
    發(fā)表于 03-02 14:10

    優(yōu)化React開發(fā)體驗

    從零構建React開發(fā)環(huán)境(四)
    發(fā)表于 04-01 16:00

    基于react父組件傳值給子組件的例子說明state和props

    react-9 state , props和map 循環(huán)渲染的簡單描述
    發(fā)表于 04-12 06:12

    React優(yōu)勢,react學習筆記分享

    1、React優(yōu)勢react適合大型團隊的開發(fā),每個人負責自己的組件,開發(fā)完畢之后由react渲染到前端頁面
    發(fā)表于 10-27 06:53

    求助,imageProgress Widget--調(diào)用setValue()時是否重新渲染整個進度?

    關于 imageProgress 小部件,有人能告訴我在調(diào)用函數(shù) setValue() 時整個矩形是否被重新渲染(無效)了嗎?或者只渲染正在改變的部分?在我看來是的。如果只渲染變化的部
    發(fā)表于 01-30 06:01

    react 渲染html字符串

    React Fiber中,render函數(shù)可以直接返回一個字符串了,換言之,一個組件可以直接渲染為一個字符串,而不是必須渲染為一個HTML模樣的物體。 舉個例子,下面這個控件LongString
    發(fā)表于 09-28 19:31 ?0次下載
    <b class='flag-5'>react</b> <b class='flag-5'>渲染</b>html字符串

    前端渲染引擎的優(yōu)勢分析

    React、Vue、Angular等均屬于MVVM模式,在一些只需完成數(shù)據(jù)和模板簡單渲染的場合,顯得笨重且學習成本較高,而解決該問題非常優(yōu)秀框架之一是doT.js,本文將對它進行詳解。 背景 前端
    發(fā)表于 09-30 13:14 ?0次下載
    前端<b class='flag-5'>渲染</b>引擎的優(yōu)勢分析

    詳談 Vue 和 React 的八大區(qū)別

    為什么 React 不精確監(jiān)聽數(shù)據(jù)變化呢 ?這是因為 Vue 和 React 設計理念上的區(qū)別, Vue 使用的是可變數(shù)據(jù),而React更強調(diào)數(shù)據(jù)的不可變。所以應該說沒有好壞之分,Vue更加簡單,而
    的頭像 發(fā)表于 09-15 15:27 ?8410次閱讀
    詳談 Vue 和 <b class='flag-5'>React</b> 的八大區(qū)別

    React-in-patterns React開發(fā)設計模式/技術列表

    react-in-patterns.zip
    發(fā)表于 04-19 11:28 ?0次下載
    <b class='flag-5'>React</b>-in-patterns <b class='flag-5'>React</b>開發(fā)設計模式/技術列表

    React Sight React組件層次可視化工具

    ./oschina_soft/React-Sight.zip
    發(fā)表于 05-18 15:36 ?4次下載
    <b class='flag-5'>React</b> Sight <b class='flag-5'>React</b>組件層次可視化工具

    React Native for Windows使用React構建原生Windows應用

    ./oschina_soft/react-native-windows.zip
    發(fā)表于 06-22 10:06 ?1次下載
    <b class='flag-5'>React</b> Native for Windows使用<b class='flag-5'>React</b>構建原生Windows應用

    React正在經(jīng)歷Angular.js的時刻嗎?

    文章指出,React 的核心仍然是一個視圖庫,這一點沒有改變:使用 React 服務器組件,您仍然可以使用 JSX 構建組件,并渲染作為 props 傳遞的動態(tài)內(nèi)容。但是,除此之外,服務器組件中
    的頭像 發(fā)表于 07-17 16:27 ?690次閱讀
    <b class='flag-5'>React</b>正在經(jīng)歷Angular.js的時刻嗎?

    前端框架的Signals有何優(yōu)勢?

    這在 React 中是不可能做到的,React 是基于視圖驅動的,狀態(tài)改變會重新執(zhí)行整個渲染函數(shù),并且 React 完全無法識別狀態(tài)是如何被
    的頭像 發(fā)表于 10-11 11:04 ?883次閱讀

    簡述大前端技術棧的渲染原理

    應用開發(fā):Android、iOS、鴻蒙(HarmonyOS)等; ?Web前端框架:Vue、React、Angular等; ?小程序開發(fā):微信小程序、京東小程序、支付寶小程序等; ?跨平臺解決方案:React Native、Flutter、Taro、Weex等。 什么是
    的頭像 發(fā)表于 11-07 10:11 ?664次閱讀

    使用SSR構建React應用的步驟

    使用SSR(Server-Side Rendering,服務器端渲染)構建React應用的步驟通常包括以下幾個階段: 一、項目初始化與配置 創(chuàng)建React項目 : 可以使用Create Rea
    的頭像 發(fā)表于 11-18 11:30 ?842次閱讀