亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

開發React應用的實用技巧有哪些

發布時間:2021-11-25 18:51:04 來源:億速云 閱讀:182 作者:柒染 欄目:開發技術

這篇文章將為大家詳細講解有關開發React應用的實用技巧有哪些,文章內容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。

背景

Hooks 自推出以來就很火, 它改變了我們編寫React 代碼的方式, 有助于我們寫更簡潔的代碼。

正文

1. 使用字符串來定義一個React元素

舉個簡單的例子:

// 我們可以通過把一個字符串'p' 賦值給一個變量, 就像:import React from 'react'const MyComponent = 'p'function App() {  return (    <>      <MyComponent>        <h4>I am inside a {'<p />'} element</h4>      </MyComponent>    </>  )}

React 內部會調用 React.createElement, 使用這個字符串來生成這個元素。

另外, 你也可以顯式的定義component 來決定渲染的內容, 比如:

// 定義一個MyComponentfunction MyComponent({ component: Component = 'p', name, age, email }) {    return (    <Component>      <h2>Hi {name} </h2>      <>        <h7>You are {age} years old</h7>        <small>Your email is {email}</small>      </>    </Component>  )}

適用方式:

function App() {  return (    <>      <MyComponent component="p" name="KK" age={18} email="xxx@gmail.com">    </>  )}

這種方式, 你也可以傳入一個自定義的組件, 比如:

function Dashboard({ children }) {  return (    <p style={{ padding: '25px 12px' }}>      {children}    </p>  )}function App() {  return (    <>      <MyComponent component={Dashboard} name="KK" age={18} email="xxx@gmail.com">    </>  )}

如果你遇到處理一類相似的元素或者組件,可以通過這種自定義的方式抽象出來,簡化你的代碼。

舉個現實的例子:

比如我們現在要做一個貨物打包的需求, 可以單個打, 也可以批量打, 針對共同點可以寫自定義組件:

import React from 'react'import withTranslate from '@components/withTranslate'import PackComponent from './PackComponent'import usePack, { check } from './usePack'let PackEditor = (props) => {  const packRes = usePack(props)  return (    <PackComponent      {...packRes}    />  )}PackEditor = withTranslate(PackEditor)PackEditor.check = checkexport default PackEditor

這樣在不同的業務模塊中, 就可以靈活的使用了, 非常方便。

2. 定義錯誤邊界

在Javascript里,我們都是使用 try/catch 來捕捉可能發生的異常,在catch中處理錯誤。 比如:

function getFromLocalStorage(key, value) {  try {    const data = window.localStorage.get(key)    return JSON.parse(data)  } catch (error) {    console.error  }}

這樣, 即便發生了錯誤, 我們的應用也不至于崩潰白屏。

React 歸根結底也是Javascript,本質上沒什么不同, 所以同樣的使用try/catch  也沒有問題。

然而, 由于React 實現機制的原因, 發生在組件內部的Javascript 錯誤會破壞內部狀態, render會產生錯誤:

https://github.com/facebook/react/issues/4026

基于以上原因,React 團隊引入了Error Boundaries:

https://reactjs.org/docs/error-boundaries.html

Error boundaries, 其實就是React組件, 你可以用找個組件來處理它捕捉到的任何錯誤信息。

當組件樹崩潰的時候,也可以顯示你自定義的UI,作為回退。

看 React 官方提供的例子:https://reactjs.org/docs/error-boundaries.html#introducing-error-boundaries

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, errorInfo) {    // You can also log the error to an error reporting service    logErrorToMyService(error, errorInfo)  }    render() {    if (this.state.hasError) {      // You can render any custom fallback UI      return <h2>Something went wrong.</h2>    }    return this.props.children  }}

使用方式:

<ErrorBoundary>  <MyWidget /></ErrorBoundary>

Live Demo By Dan Abramov:

https://codepen.io/gaearon/pen/wqvxGa?editors=0010

3.高階組件

通俗點講, 所謂高階組件就是, 你丟一個組件進去, 增加一些屬性或操作, 再丟出來。

一般來說, 你可以把一些具備共同點的組件抽象成一個高階組件, 然后再不同的模塊中復用

比如, 我們的系統中, 有一類按鈕要加個border, 很多地方都要用到, 我們把它抽象出來:

import React from 'react'// Higher order componentconst withBorder = (Component, customStyle) => {  class WithBorder extends React.Component {    render() {      const style = {        border: this.props.customStyle ? this.props.customStyle.border : '3px solid teal'      }      return <Component style={style} {...this.props} />    }  }    return WithBorder}function MyComponent({ style, ...rest }) {  return (    <p style={style} {...rest}>        <h3>          This is my component and I am expecting some styles.        </h3>    </p>  )}export default withBorder(MyComponent, { border: '4px solid teal' })

經過withBorder裝飾的MyComponent組件, 就具備了統一border這項功能, 后面如果如果要做修改, 就可以在這個中間層統一處理, 非常方便。

在我的項目里, 也用了一些高階組件, 舉個具體的例子:

PackEditor = withTranslate(PackEditor)

我們的這個 PackEditor 就是一個增強過的組件, 增加了什么功能呢?

正如名字表述的, withTranslate, 增加了一個翻譯功能, 下面也給大家看看這個組件是怎么實現的:

import React from 'react'import { Provider } from 'react-redux'import { injectIntl } from 'react-intl'import { store } from '@redux/store'import { Intl } from './Locale'const withTranslate = BaseComponent => (props) => {  // avoid create a new component on re-render  const IntlComponent = React.useMemo(() => injectIntl(    ({ intl, ...others }) => (      <BaseComponent        intl={intl}        translate={(id, values = {}) => { // 注入翻譯方法          if (!id) { return '' }          return intl.formatMessage(            typeof id === 'string' ? { id } : id,            values          )        }}        {...others}      />    )  ), [])  IntlComponent.displayName = `withTranslate(${BaseComponent.displayName || 'BaseComponent'})`    return (    <Provider store={store}>      <Intl>        <IntlComponent          {...props}        />      </Intl>    </Provider>  )}export default withTranslate

用法很靈過:

const Editor = withTranslate(({  // ...  translate,}) => {  // ...   return (     <>      {translate('xxx')}}     </>   )})

十分的方便。

4. Render props

Rrender prop 是指一種在 React 組件之間使用一個值為函數的 prop 共享代碼的簡單技術, 和 HOC 類似, 都是組件間的邏輯復用問題

更具體地說,Render prop 是一個用于告知組件需要渲染什么內容的函數。

下面看一下簡單的例子:

以下組件跟蹤 Web 應用程序中的鼠標位置:

class Mouse extends React.Component {  state = { x: 0, y: 0 };  handleMouseMove = (event) => {    this.setState({      x: event.clientX,      y: event.clientY    });  }  render() {    return (      <p style={{ height: '100%' }} onMouseMove={this.handleMouseMove}>        <p>The current mouse position is ({this.state.x}, {this.state.y})</p>      </p>    );  }}class MouseTracker extends React.Component {  render() {    return (      <>        <h2>移動鼠標!</h2>        <Mouse />      </>    );  }}

當光標在屏幕上移動時,組件顯示其(x,y)坐標。

現在的問題是:

我們如何在另一個組件中復用這個行為?

換個說法,若另一個組件需要知道鼠標位置,我們能否封裝這一行為,以便輕松地與其他組件共享它 ??

假設產品想要這樣一個功能: 在屏幕上呈現一張在屏幕上追逐鼠標的貓的圖片。

我們或許會使用 <Cat mouse={{ x, y }} prop 來告訴組件鼠標的坐標以讓它知道圖片應該在屏幕哪個位置。

class Cat extends React.Component {  render() {    const mouse = this.props.mouse;    return (      <img src="/cat.jpg" style={{ position: 'absolute', left: mouse.x, top: mouse.y }} />    );  }}

這個需求如此簡單,你可能就直接修改Mouse組件了:

class Mouse extends React.Component {  state = { x: 0, y: 0 };  handleMouseMove = (event) => {    this.setState({      x: event.clientX,      y: event.clientY    });  }  render() {    return (      <p style={{ height: '100%' }} onMouseMove={this.handleMouseMove}>        <Cat mouse={this.state} />      </p>    );  }}

巴適~ 簡單粗暴, 一分鐘完成任務。

可是,如果下次產品再要想加條狗呢

以上的例子,雖然可以完成了貓追鼠標的需求,還沒有達到以可復用的方式真正封裝行為的目標。

當我們想要鼠標位置用于不同的用例時,我們必須創建一個新的組件,專門為該用例呈現一些東西.

這也是 render prop 的來歷:

我們可以提供一個帶有函數 prop 的 <Mouse> 組件,它能夠動態決定什么需要渲染的,而不是將 <Cat> 硬編碼到 <Mouse> 組件里.

修改一下上面的代碼:

class Cat extends React.Component {  render() {    const mouse = this.props.mouse;    return (      <img src="/cat.jpg" style={{ position: 'absolute', left: mouse.x, top: mouse.y }} />    );  }}class Mouse extends React.Component {  state = { x: 0, y: 0 };  handleMouseMove = (event) => {    this.setState({      x: event.clientX,      y: event.clientY    });  }  render() {    return (      <p style={{ height: '100%' }} onMouseMove={this.handleMouseMove}>        {this.props.render(this.state)}      </p>    );  }}class MouseTracker extends React.Component {  render() {    return (      <p>        <h2>移動鼠標!</h2>        <Mouse render={mouse => (          <Cat mouse={mouse} />        )}/>      </p>    );  }}

提供了一個render 方法,讓動態決定什么需要渲染。

事實上,render prop 是因為模式才被稱為 render prop ,不一定要用名為 render 的 prop 來使用這種模式。

任何被用于告知組件需要渲染什么內容的函數 prop, 在技術上都可以被稱為 "render prop".

另外,關于 render prop 一個有趣的事情是你可以使用帶有 render prop 的常規組件來實現大多數高階組件 (HOC)。

例如,如果你更喜歡使用 withMouse HOC 而不是 <Mouse> 組件,你可以使用帶有 render prop 的常規 <Mouse> 輕松創建一個:

function withMouse(Component) {  return class extends React.Component {    render() {      return (        <Mouse render={mouse => (          <Component {...this.props} mouse={mouse} />        )}/>      );    }  }}

也是非常的簡潔清晰。

有一點需要注意的是, 如果你在定義的render函數里創建函數, 使用 render prop 會抵消使用 React.PureComponent 帶來的優勢。

因為淺比較 props 的時候總會得到 false,并且在這種情況下每一個 render 對于 render prop 將會生成一個新的值

class Mouse extends React.PureComponent {  // 與上面相同的代碼......}class MouseTracker extends React.Component {  render() {    return (      <>        <Mouse render={mouse => ( // 這是不好的! 每個渲染的 `render` prop的值將會是不同的。          <Cat mouse={mouse} />        )}/>      </>    );  }}

在這樣例子中,每次 <MouseTracker> 渲染,它會生成一個新的函數作為 <Mouse render> 的 prop,因而在同時也抵消了繼承自 React.PureComponent 的 <Mouse> 組件的效果.

為了繞過這一問題,有時你可以定義一個 prop 作為實例方法,類似這樣:

class MouseTracker extends React.Component {  renderTheCat(mouse) {    return <Cat mouse={mouse} />;  }  render() {    return (      <p>        <h2>Move the mouse around!</h2>        <Mouse render={this.renderTheCat} />      </p>    );  }}

關于開發React應用的實用技巧有哪些就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

哈巴河县| 潼南县| 邵阳县| 民乐县| 五寨县| 浙江省| 老河口市| 平江县| 马山县| 莒南县| 开原市| 鞍山市| 北流市| 融水| 清新县| 连山| 水城县| 彰化市| 栾川县| 渝北区| 九寨沟县| 沧州市| 开封县| 三明市| 乃东县| 景宁| 稷山县| 温州市| 辽宁省| 商水县| 济源市| 额尔古纳市| 辽阳市| 柯坪县| 清新县| 清丰县| 繁峙县| 炉霍县| 揭东县| 浑源县| 凤冈县|