成為高級 React 開發(fā)你需要知道的知識點

簡評:除了常見的 HOC 和 RenderProp 技巧,作者介紹了 7 個有用的知識點。

使用 Fragment 而不是 div

很多時候我們想要處理多個 component,但是 render 只允許返回一個 component,為了處理這個問題很可以使用 <div /> 標簽來包裝所有的 component 。但這會添加額外的 HTML 元素。所以官方的建議是推薦使用 React Fragments 來處理這個問題。

import React, { Fragment } from 'react';

function ListItem({ item }) {
  return (

    <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>
  );
}

context 用起來

Context 提供了一種方式將數(shù)據(jù)傳遞到整個 component 樹中,而不必手動為每一層 component 傳遞 props。

因此,如果你有多個需要值的 component,建議使用 context。如果只有一個子 component 需要使用這個值建議使用 compositions。

最少使用一個 Error Boundaries

React 16 附帶了一個驚艷的功能 Error Boundaries。使用 Error Boundaries 我們可以處理這種問題,子組件出現(xiàn)錯誤不會導(dǎo)致整個應(yīng)用報錯和白屏。

舉個例子: 定義一個 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 方法。

在生產(chǎn)環(huán)境中使用 production build

官網(wǎng)提供了很多提高性能的 配置。只需要 10 分鐘即可給你的應(yīng)用帶來質(zhì)的飛躍,在部署到生產(chǎn)環(huán)境前別忘了檢查它們。

使用 Refs 來操縱元素

我們可以使用 Refs 來觸發(fā)動畫,文本選擇或焦點管理。

例如:

我們可以 獲取 inpout DOM 節(jié)點引用。

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 創(chuàng)建應(yīng)用或使用 NextJs 會自動創(chuàng)建一個 webpack 配置文件,webpack 會將整個應(yīng)用打包到一個文件中,如果應(yīng)用程序變得復(fù)雜或者添加第三方庫都會導(dǎo)致最終生成的文件變大,導(dǎo)致應(yīng)用訪問速度變慢。這時候可以使用代碼拆分,創(chuàng)建多個輸出,在需要的時候才加載對應(yīng)的包,可以大大改善網(wǎng)頁加載時間。

可以使用 React.lazy 來實現(xiàn)代碼拆分。

使用方式也很簡單,這里簡單實現(xiàn)一個基于路由代碼分割的例子:

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 暫不支持服務(wù)端渲染,如果服務(wù)端渲染想要實現(xiàn)這個功能可以使用 React Loadable

靜態(tài)類型檢查

JavaScript 不會對類型進行檢查,這可能導(dǎo)致很多的問題??梢允褂妙愋蜋z查器(例如 Flow)來幫助我們提前發(fā)現(xiàn)錯誤。Flow 是有 facebook 開發(fā)的類型檢查器,可以給變量、函數(shù)和 React Component 添加而外的注釋是一個不錯的選擇。


原文鏈接:Concepts to become an advanced React developer
推薦閱讀:改進 GitHub 工作流的 15 個建議

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容