react v.16的新特性學習
1、Fragment
新版本的render可以返回陣列、字串、react元件、數字、boolean值
v15.x必須要一個標籤來包裹
Before v16
return (
<div>
<label htmlFor="name">名字:</label>
<input id="name" type="text" placeholder="請輸入名字"/>
<button>搜尋</button>
</div>
);
When v16.0.0
return (
[
<label htmlFor="name">名字:</label>,
<input id="name" type="text" placeholder="請輸入名字"/>,
<button>搜尋</button>
]
);
Now v16.2.0
return (
<React.Fragment>
<label htmlFor="name">名字:</label>
<input id="name" type="text" placeholder="請輸入名字"/>
<button>搜尋</button>
</React.Fragment>
);
片段(fragments) 可以讓你將子元素列表新增到一個分組中,並且不會在DOM中增加額外節點。key 是唯一可以傳遞給 Fragment 的屬性
return (
<dl>
{props.items.map(item => (
// 沒有`key`,將會觸發一個key警告
<React.Fragment key={item.id}>
<dt>{item.term}</dt>
<dd>{item.description}</dd>
</React.Fragment>
))}
</dl>
);
簡明寫法<>
return (
<>
<label htmlFor="name">名字:</label>
<input id="name" type="text" placeholder="請輸入名字"/>
<button>搜尋</button>
</>
);
DOM Fragment
const select = document.getElementById('select')
const values = [1, 2, 3]
const fragment = document.createDocumentFragment()
values.map(item => {
const option = document.createElement('option')
option.value = item
option.innerHTML = `小明${item}號`
fragment.appendChild(option)
})
select.appendChild(fragment)
2、Portals
Portals是reactjs16提供的官方解決方案,使得元件可以脫離父元件層級掛載在DOM樹的任何位置。
普通情況下,元件的render函式返回的元素會被掛載在它的父級元件上。
然而,有些元素需要被掛載在更高層級的位置。最典型的應用場景:當父元件具有overflow: hidden或者z-index的樣式設定時,元件有可能被其他元素遮擋,就可以考慮使用Portal使元件的掛載脫離父元件。
元件的掛載點雖然可以脫離父元件,但元件的事件通過冒泡機制仍可以傳給父元件。
<body>
<div id="bd"></div>
<div id="modal"></div>
</body>
render(
<App>
<SearchBox>
<Modal>
<div>模態框</div>
</Modal>
</SearchBox>
</App>,
document.getElementById('bd'),
() => {
console.log(arguments)
})
cl
ass App extends Component{
constructor(options) {
super(options)
this.handleClick = this.handleClick.bind(this)
}
handleClick() {
alert('react component tree propagation!')
}
render() {
return <div className="app" onClick={this.handleClick}>
{this.props.children}
</div>
}
}
class Modal extends Component {
constructor(options) {
super(options)
}
render() {
return createPortal(this.props.children, document.getElementById('modal'))
}
}
<div id="bd">
<div class="app">
<label for="name">名字:</label>
<input type="text" id="name" placeholder="請輸入名字">
<button>搜尋</button>
</div>
</div>
<div id="modal">
<div>模態框</div>
</div>
<App>
<div className="app" onClick=bound handleClick()>
<SearchBox>
<labelhtmlFor="name">名字:</label>
<inputid="name"type="text"placeholder="請輸入名字"></input>
<button>搜尋</button>
<Modal>
<ReactPortal target=HTMLDivElement{…}>
<div>模態框</div>
</ReactPortal>
</Modal>
</SearchBox>
</div>
</App>
Before portals
ReactDom.render(reactChild, container, callback)
ReactDom.unmountComponentAtNode(container)
ReactDom.unstable_renderSubtreeIntoContainer(
context,
reactChild,
domNode,
callback
)
ReactDom.unmountComponentAtNode(container)
render: ReactMount._renderSubtreeIntoContainer(null, reactChild, container, callback )
unstable_renderSubtreeIntoContainer: ReactMount._renderSubtreeIntoContainer(context, reactChild, container, callback)
3、Error Boundaries
之前react在渲染過程中或者是生命週期內出現了致命的錯誤,react會從根元件上把所有的元件都解除安裝下來,以防止展現錯誤的資料,但這不是最好的使用者體驗。React 16修復了這一點,引入了Error Boundary的概念,中文譯為“錯誤邊界”,當某個元件發生錯誤時,我們可以通過Error Boundary捕獲到錯誤並對錯誤做優雅處理。(注:它並不能捕獲runtime所有的錯誤,比如元件回撥事件裡的錯誤,可以把它想象成傳統的try-catch語句)
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
// 新增了componentDidCatch這個生命週期函式,它可以捕獲自身及子樹上的錯誤並對錯誤做優雅處理,包括上報錯誤日誌、展示出錯提示,而不是解除安裝整個元件樹。
componentDidCatch(error, info) {
// 錯誤代理元件的展示與否
this.setState({ hasError: true });
// 在這裡我們可以對錯誤進行記錄
logErrorToMyService(error, info);
}
render() {
if (this.state.hasError) {
// 在這裡我們可以書寫自己想要展示的ui元件
return <h1>Something went wrong.</h1>;
}
return this.props.children;
}
}
上面的元件是當頁面中有錯誤時我們想要展示的效果,具體用法如下:
render(){
return (
<div>
<ErrorBoundary> // 外層元件我們定義的錯誤元件
<Profile user={this.state.user} /> // 內層元件是我們將要監視的自定義元件
</ErrorBoundary>
<button onClick={this.onClick}>Update</button>
</div>
)
}
這個元件能夠不僅僅能夠監聽到本元件的錯誤,連同它下面的子元件的錯誤也可以監聽到
不能捕獲的錯誤
- 事件處理
- 非同步回撥
- 服務端渲染
- error boundary元件自身丟擲的錯誤(只能由父級捕獲)
react遇到未捕獲的錯誤會怎麼辦
對 React16 來說,一個未捕獲的錯誤會導致整個應用不能被掛載
4、setState傳入null時不會再觸發更新
之前的setState不管傳入什麼只要呼叫了這麼方法就會渲染
selectCity(e){
const newValue = e.target.value;
this.setState((state)=>{
if(state.city===newValue){
return null;
}
return {city:newValue}
})
)
5、v16.0支援自定義的dom屬性
之前的版本對於自定義屬性react會在屬性前加上data-**來進行處理,現在對於部分屬性去除了這種寫法,擁抱了原生dom,這樣可以減少react的程式碼,提升了效能
6、其他
更好的伺服器端渲染:React 16的SSR被完全重寫,新的實現非常快,接近3倍效能於React 15,現在提供一種流模式streaming,可以更快地把渲染的位元組傳送到客戶端。
react v16採用了最新的技術“Fiber.”
React Server Side Rendering 解決 SPA 應用的 SEO 問題
相關推薦
react v.16的新特性學習
1、Fragment 新版本的render可以返回陣列、字串、react元件、數字、boolean值 v15.x必須要一個標籤來包裹 Before v16 return ( <div> <label
React 16 新特性
2017年9月26日React 16釋出,通過官網和示例瞭解一下新特性。 React 16更新 新js環境要求 react16依靠Map和Set集合和requestAnimationFra
java 新特性學習筆記
sets arp string get pen option ring true read java 1.7 Files.write(path,list,StandardCharsets.UTF_8,StandardOpenOption.APPEND); St
JDK7新特性學習之 --- switch的表達式
bre image http 例如 style 之前 字符 深入理解 編譯錯誤 JDK7之前,switch中表達式只能是char、byte、short、int及其對應的包裝類和枚舉類型。JDK7之後java中新增加了String類型作為switch的表達式之一。 但
java8新特性學習:stream與lambda
包含 term strong java statistic 管道 特定 getname java8新特性 Streams api 對 Stream 的使用就是實現一個 filter-map-reduce 過程,產生一個最終結果,或者導致一個副作用(side effect)
c++11 多線程新特性學習 (1) 管理線程
his on() argc 等待 通過 運行 int 選擇 如果 1.基礎介紹 c++11中,線程是通過std::thread對象來開始的,用法為 #include<thread> //必須包含的頭文件 void do_work(){ std::c
Java8新特性學習-總結
1. 介面的擴充套件方法 Java8允許給介面新增一個非抽象的方法,只需要使用default關鍵字即可,這個特徵又叫做擴充套件方法。 程式碼:定義Formula 介面,接口裡定義非抽象方法sqrt,並用default修飾 interface Formula { do
php7新特性學習
1、標量型別宣告 在函式/方法的引數及返回值處宣告資料型別為某個具體的資料型別,則必須傳入或返回對應的資料型別,否則會報錯。 function inputint(int $a) { echo $a; } function returnArray(): array {
C++11新特性學習筆記—使用花括號就地初始化
這個特性是真正極好的!非常好用且方便!降低工作量! 如果一個類有很多成員變數A,B,C,D...,而且有很多不同版本的建構函式c1,c2,c3....,每個不同的建構函式可能會選擇不同的成員
JDK8 併發新特性學習 (一) CompletableFuture
JDK8 併發新特性學習 (一) CompletableFuture JDK 8 java.util.concurrent新增加的兩個介面和四個類 CompletableFutre.AsynchronousCompletionTask 一個沒有方法的裝飾介面,用來標識非
Tomcat 7 新特性學習之一
Tomcat 7 Beta版本出來已經有段時間了,看了JavaEye上的朋友,還是有幾個非常勤奮每天都在學習的朋友,他們能夠每天學習,堅持下來,實屬不易,他們非常的年輕,有幾個,我還見過面,小夥子們的好學精神實在讓人敬佩。這個社會很浮躁,我自己也是這樣,尤其在杭州這種城市裡生
C11新特性學習
#include <cstdio> #include <iostream> #include <Windows.h> //#define _AFXDLL //#include "afx.h" #include <strsafe.h> #in
2019 年的 JavaScript 新特性學習指南
昨天在瀏覽 Babel 網站時,看到它的 blog 有一篇新的文章,說 Babel 釋出了新的程式碼支援 class 的私有屬性和方法。 這著實讓我頭腦混亂,到底在哪可以瞭解到最新的規範?而這些規範又是否被支援?支援到什麼程度?完全沒有頭緒。 自從 ES6 規範釋出以來,帶來很多新的特性,而我們在消化這些
Java8新特性學習-Stream的Reduce及Collect方法詳解
Stream的使用方法在http://blog.csdn.net/icarusliu/article/details/79495534一文中已經做了初步的介紹,但它的Reduce及Collect方法由於較為複雜未進行總結,現單獨對這兩個方法進行學習。 為簡化理
Kubernetes 1.6新特性學習:RBAC授權
概述 Kuberntes中API Server的訪問控制過程圖示如下: 在Kubernetes中,授權(authorization)是在認證(authentication)之後的一個步驟。授權就是決定一個使用者(普通使用者或ServiceAccount)是否有權請
Java 8 新特性——學習總結
Java 8 新特性 Java 9都快出來了,把Java 8學習一波,很多語言特性在別的語言中都見過,一些優秀的語言特性,好語言都會整合! 程式設計風格 Java8希望有自己的程式設計風格,並與Java7分開,以下展示以下兩者的區別。 package com.tenc
C++11新特性學習筆記—final和override關鍵字
一、final關鍵字 為什麼c++現在才提供final這個關鍵字?很奇怪。 和Java一樣,c++中的final關鍵字是用來修飾一個函式,防止這個
Java8 新特性學習
1、介面中的預設方法 Java8中允許介面中包含具有具體實現的方法,這種方法被稱為“預設方法”,使用default關鍵字修飾。 如: public interface MyInterface { String notDefault();
JDK8新特性學習(一) Lambda表示式和函式式介面
Lambda表示式和函式式介面 剛進公司時,公司正處於由JDK7換用JDK8的時間短,之所以更換JDK版本,聽說是公司業務中需要用到JDK8的一些新特性。鑑於我現在也無事可做,姑且來學習總結一下JDK8的一些特性吧。水平有限,這篇勉強算是對他人部落格上零
list 集合排序,java8新特性,學習一下
最近做一個專案,遇到了list<Entity>需要按時間倒敘排列發現Java8新特性封裝的比較好:例子:List<Entity> list = Lists.newArrayLis