簡評:除了常見的 HOC 和 RenderProp 技巧,做者介紹了 7 個有用的知識點。node
使用 Fragment 而不是 divreact
不少時候咱們想要處理多個 component,可是 render 只容許返回一個 component,爲了處理這個問題很可使用 <div /> 標籤來包裝全部的 component 。但這會添加額外的 HTML 元素。因此官方的建議是推薦使用 React Fragments 來處理這個問題。webpack
import React, { Fragment } from 'react'; function ListItem({ item }) { return (web
<Fragment> <dt>{item.term}</dt> <dd>{item.description}</dd> </Fragment> // 也可使用 <>....</> 來替換 <Fragment> // 等同於 // <> // <dt>{item.term}</dt> // <dd>{item.description}</dd> // </>
);} function Glossary(props) { return ( <dl> {props.items.map(item => ( <ListItem item={item} key={item.id} /> ))} </dl> );}react-router
context 用起來app
Context 提供了一種方式將數據傳遞到整個 component 樹中,而沒必要手動爲每一層 component 傳遞 props。 所以,若是你有多個須要值的 component,建議使用 context。若是隻有一個子 component 須要使用這個值建議使用 compositions。dom
最少使用一個 Error Boundaries函數
React 16 附帶了一個驚豔的功能 Error Boundaries。使用 Error Boundaries 咱們能夠處理這種問題,子組件出現錯誤不會致使整個應用報錯和白屏。性能
舉個例子: 定義一個 ErrorBoundary 組件動畫
class ErrorBoundary extends React.Component { constructor(props) { super(props); this.state = { hasError: false }; }static getDerivedStateFromError(error) { // Update state so the next render will show the fallback UI. return { hasError: true }; }componentDidCatch(error, info) { // You can also log the error to an error reporting service logErrorToMyService(error, info); }render() { if (this.state.hasError) { // You can render any custom fallback UI return <h1>Something went wrong.</h1>; }return this.props.children; }}
用法和其餘組件同樣簡單:
<ErrorBoundary> <MyWidget /></ErrorBoundary>
注意:React15 中的 unstable_handleError 方法再也不有效,須要替換成 componentDidCatch 方法。
在生產環境中使用 production build
官網提供了不少提升性能的 配置。只須要 10 分鐘便可給你的應用帶來質的飛躍,在部署到生產環境前別忘了檢查它們。
使用 Refs 來操縱元素
咱們可使用 Refs 來觸發動畫,文本選擇或焦點管理。
例如: 咱們能夠 獲取 inpout DOM 節點引用。
class CustomTextInput extends React.Component { constructor(props) { super(props); // Create a ref to store the textInput DOM element this.textInput = React.createRef(); } render() { // Use the ref
callback to store a reference to the text input DOM // element in an instance field (for example, this.textInput). return ( <input type="text" ref={this.textInput} /> ); } }
而後就能夠在合適的時機聚焦這個 <input /> focus() { // Explicitly focus the text input using the raw DOM API // Note: we're accessing "current" to get the DOM node this.textInput.current.focus(); }
使用代碼拆分
若是你使用 create-react-app 建立應用或使用 NextJs 會自動建立一個 webpack 配置文件,webpack 會將整個應用打包到一個文件中,若是應用程序變得複雜或者添加第三方庫都會致使最終生成的文件變大,致使應用訪問速度變慢。這時候可使用代碼拆分,建立多個輸出,在須要的時候才加載對應的包,能夠大大改善網頁加載時間。
可使用 React.lazy 來實現代碼拆分。
使用方式也很簡單,這裏簡單實現一個基於路由代碼分割的例子:
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';import React, { Suspense, lazy } from 'react';const Home = lazy(() => import('./routes/Home'));const About = lazy(() => import('./routes/About'));const App = () => ( <Router> <Suspense fallback={<div>Loading...</div>}> <Switch> <Route exact path="/" component={Home}/> <Route path="/about" component={About}/> </Switch> </Suspense> </Router>);
注意: React.lazy 和 Suspense 暫不支持服務端渲染,若是服務端渲染想要實現這個功能可使用 React Loadable。
靜態類型檢查
JavaScript 不會對類型進行檢查,這可能致使不少的問題。可使用類型檢查器(例如 Flow)來幫助咱們提早發現錯誤。Flow 是有 facebook 開發的類型檢查器,能夠給變量、函數和 React Component 添加而外的註釋是一個不錯的選擇。
原文:Concepts to become an advanced React developer