国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

React 模式(中文版)

hzx / 1424人閱讀

摘要:渲染屬性這里有個組件,使用了一個渲染回調函數。這個狀態被提升到了容器中,通過添加回調函數,回調中可以更新本地狀態。這個是正常的受控的輸入不允許變更,這使得這個模式成為可能。

中文版:https://reactpatterns.cn/
原版:https://reactpatterns.com

函數組件 (Function component)

函數組件 是最簡單的一種聲明可復用組件的方法

他們就是一些簡單的函數。

function Greeting() {
  return 
Hi there!
; }

從第一個形參中獲取屬性集 (props)

function Greeting(props) {
  return 
Hi {props.name}!
; }

按自己的需要可以在函數組件中定義任意變量

最后一定要返回你的 React 組件。

function Greeting(props) {
  let style = {
    fontWeight: "bold",
    color: context.color
  };

  return 
Hi {props.name}!
; }

使用 defaultProps 為任意必有屬性設置默認值

function Greeting(props) {
  return 
Hi {props.name}!
; } Greeting.defaultProps = { name: "Guest" };
屬性解構 (Destructuring props)

解構賦值 是一種 JavaScript 特性。

出自 ES2015 版的 JavaScript 新規范。

所以看起來可能并不常見。

好比字面量賦值的反轉形式。

let person = { name: "chantastic" };
let { name } = person;

同樣適用于數組。

let things = ["one", "two"];
let [first, second] = things;

解構賦值被用在很多 函數組件 中。

下面聲明的這些組件是相同的。

function Greeting(props) {
  return 
Hi {props.name}!
; } function Greeting({ name }) { return
Hi {name}!
; }

有一種語法可以在對象中收集剩余屬性。

叫做 剩余參數,看起來就像這樣。

function Greeting({ name, ...restProps }) {
  return 
Hi {name}!
; }

那三個點 (...) 會把所有的剩余屬性分配給 restProps 對象

然而,你能使用 restProps 做些什么呢?

繼續往下看...

JSX 中的屬性展開 (JSX spread attributes)

屬性展開是 JSX 中的一個的特性。

它是一種語法,專門用來把對象上的屬性轉換成 JSX 中的屬性

參考上面的 屬性解構),
我們可以 擴散 restProps 對象的所有屬性到 div 元素上

function Greeting({ name, ...restProps }) {
  return 
Hi {name}!
; }

這讓 Gretting 組件變得非常靈活。

我們可以通過傳給 Gretting 組件 DOM 屬性并確定這些屬性一定會被傳到 div

避免傳遞非 DOM 屬性到組件上。
解構賦值是如此的受歡迎,是因為它可以分離 組件特定的屬性DOM/平臺特定屬性

function Greeting({ name, ...platformProps }) {
  return 
Hi {name}!
; }
合并解構屬性和其它值 (Merge destructured props with other values)

組件就是一種抽象。

好的抽象是可以擴展的。

比如說下面這個組件使用 class 屬性來給按鈕添加樣式。

function MyButton(props) {
  return 

一般情況下這樣做就夠了,除非我們需要擴展其它的樣式類

Delete...

在這個例子中把 btn 替換成 delete-btn

JSX 中的屬性展開) 對先后順序是敏感的

擴散屬性中的 className 會覆蓋組件上的 className

我們可以改變它兩的順序,但是目前來說 className 只有 btn

function MyButton(props) {
  return 

我們需要使用解構賦值來合并入參 props 中的 className 和基礎的(組件中的) className
可以通過把所有的值放在一個數組里面,然后使用一個空格連接它們。

function MyButton({ className, ...props }) {
  let classNames = ["btn", className].join(" ");

  return 

為了保證 undefined 不被顯示在 className 上,可以使用 默認值。

function MyButton({ className = "", ...props }) {
  let classNames = ["btn", className].join(" ");

  return 
條件渲染 (Conditional rendering)

不可以在一個組件聲明中使用 if/else 語句
You can"t use if/else statements inside a component declarations.
所以可以使用 條件(三元)運算符 和 短路計算。

如果
{
  condition && Rendered when `truthy`;
}
除非
{
  condition || Rendered when `falsy`;
}
如果-否則
{
  condition ? (
    Rendered when `truthy`
  ) : (
    Rendered when `falsy`
  );
}
子元素類型 (Children types)

很多類型都可以做為 React 的子元素。

多數情況下會是 數組 或者 字符串

字符串 String
Hello World!
數組 Array
{["Hello ", World, "!"]}
數組做為子元素 (Array as children)

將數組做為子元素是很常見的。

列表是如何在 React 中被繪制的。

我們使用 map() 方法創建一個新的 React 元素數組

    {["first", "second"].map(item => (
  • {item}
  • ))}

這和使用字面量數組是一樣的。

    {[
  • first
  • ,
  • second
  • ]}

這個模式可以聯合解構、JSX 屬性擴散以及其它組件一起使用,看起來簡潔無比

    {arrayOfMessageObjects.map(({ id, ...message }) => ( ))}
函數做為子元素 (Function as children)

React 組件不支持函數類型的子元素。

然而 渲染屬性 是一種可以創建組件并以函數作為子元素的模式。

渲染屬性 (Render prop)

這里有個組件,使用了一個渲染回調函數 children。

這樣寫并沒有什么用,但是可以做為入門的簡單例子。

const Width = ({ children }) => children(500);

組件把 children 做為函數調用,同時還可以傳一些參數。上面這個 500 就是實參。

為了使用這個組件,我們可以在調用組件的時候傳入一個子元素,這個子元素就是一個函數。

{width => 
window is {width}
}

我們可以得到下面的輸出。

window is 500

有了這個組件,我們就可以用它來做渲染策略。


  {width => (width > 600 ? 
min-width requirement met!
: null)}

如果有更復雜的條件判斷,我們可以使用這個組件來封裝另外一個新組件來利用原來的邏輯。

const MinWidth = ({ width: minWidth, children }) => (
  {width => (width > minWidth ? children : null)}
);

顯然,一個靜態的 Width 組件并沒有什么用處,但是給它綁定一些瀏覽器事件就不一樣了。下面有個實現的例子。

class WindowWidth extends React.Component {
  constructor() {
    super();
    this.state = { width: 0 };
  }

  componentDidMount() {
    this.setState(
      { width: window.innerWidth },
      window.addEventListener("resize", ({ target }) =>
        this.setState({ width: target.innerWidth })
      )
    );
  }

  render() {
    return this.props.children(this.state.width);
  }
}

許多開發人員都喜歡 高階組件 來實現這種功能。但這只是個人喜好問題。

子組件的傳遞 (Children pass-through)

你可能會創建一個組件,這個組件會使用 context 并且渲染它的子元素。

class SomeContextProvider extends React.Component {
  getChildContext() {
    return { some: "context" };
  }

  render() {
    // 如果能直接返回 `children` 就完美了
  }
}

你將面臨一個選擇。把 children 包在一個 div 中并返回,或者直接返回 children。第一種情況需要要你添加額外的標記(這可能會影響到你的樣式)。第二種將產生一個沒什么用處的錯誤。

// option 1: extra div
return 
{children}
; // option 2: unhelpful errors return children;

最好把 children 做為一種不透明的數據類型對待。React 提供了 React.Children 方法來處理 children

return React.Children.only(this.props.children);
代理組件 (Proxy component)

(我并不確定這個名字的準確叫法 譯:代理、中介、裝飾?)

按鈕在 web 應用中隨處可見。并且所有的按鈕都需要一個 type="button" 的屬性。

重復的寫這些屬性很容易出錯。我們可以寫一個高層組件來代理 props 到底層組件。

const Button = props =>
  

我們可以使用 Button 組件代替 button 元素,并確保 type 屬性始終是 button。


// 
樣式組件 (Style component)

這也是一種 代理組件,用來處理樣式。

假如我們有一個按鈕,它使用了「primary」做為樣式類。

我們使用一些單一功能組件來生成上面的結構。

import classnames from "classnames";

const PrimaryBtn = props => ;

const Btn = ({ className, primary, ...props }) => (
  

可以可視化的展示成下面的樣子。

PrimaryBtn()
  ? Btn({primary: true})
    ? Button({className: "btn btn-primary"}, type: "button"})
      ? ""

使用這些組件,下面的這幾種方式會得到一致的結果。



這對于樣式維護來說是非常好的。它將樣式的所有關注點分離到單個組件上。

組織事件 (Event switch)

當我們在寫事件處理函數的時候,通常會使用 handle{事件名字} 的命名方式。

handleClick(e) { /* do something */ }

當需要添加很多事件處理函數的時候,這些函數名字會顯得很重復。這些函數的名字并沒有什么價值,因為它們只代理了一些動作或者函數。

handleClick() { require("./actions/doStuff")(/* action stuff */) }
handleMouseEnter() { this.setState({ hovered: true }) }
handleMouseLeave() { this.setState({ hovered: false }) }

可以考慮寫一個事件處理函數來根據不同的 event.type 來組織事件。

handleEvent({type}) {
  switch(type) {
    case "click":
      return require("./actions/doStuff")(/* action dates */)
    case "mouseenter":
      return this.setState({ hovered: true })
    case "mouseleave":
      return this.setState({ hovered: false })
    default:
      return console.warn(`No case for event type "${type}"`)
  }
}

另外,對于簡單的組件,你可以在組件中使用箭頭函數直接調用導入的動作或者函數

someImportedAction({ action: "DO_STUFF" })}

在遇到性能問題之前,不要擔心性能優化。真的不要

布局組件 (Layout component)

布局組件表現為一些靜態 DOM 元素的形式。它們一般并不需要經常更新。

就像下面的這個組件一樣,兩邊各自渲染了一個 children。

}
  rightSide={}
/>

我們可以優化這個組件。

HorizontalSplit 組件是兩個子組件的父元素,我們可以告訴組件永遠都不要更新

class HorizontalSplit extends React.Component {
  shouldComponentUpdate() {
    return false;
  }

  render() {
    
      
{this.props.leftSide}
{this.props.rightSide}
} }
容器組件 (Container component)

「容器用來獲取數據然后渲染到子組件上,僅僅如此。」—Jason Bonta

這有一個 CommentList 組件。

const CommentList = ({ comments }) => (
  
    {comments.map(comment => (
  • {comment.body}-{comment.author}
  • ))}
);

我們可以創建一個新組件來負責獲取數據渲染到上面的 CommentList 函數組件中。

class CommentListContainer extends React.Component {
  constructor() {
    super()
    this.state = { comments: [] }
  }

  componentDidMount() {
    $.ajax({
      url: "/my-comments.json",
      dataType: "json",
      success: comments =>
        this.setState({comments: comments});
    })
  }

  render() {
    return 
  }
}

對于不同的應用上下文,我們可以寫不同的容器組件。

高階組件 (Higher-order component)

高階函數 是至少滿足下列一個條件的函數:

接受一個或多個函數作為輸入

輸出一個函數

所以高階組件又是什么呢?

如果你已經用過 容器組件, 這僅僅是一些泛化的組件, 包裹在一個函數中。

讓我們以 Greeting 組件開始

const Greeting = ({ name }) => {
  if (!name) {
    return 
連接中...
; } return
Hi {name}!
; };

如果 props.name 存在,組件會渲染這個值。否則將展示「連接中...」。現在來添加點高階的感覺

const Connect = ComposedComponent =>
  class extends React.Component {
    constructor() {
      super();
      this.state = { name: "" };
    }

    componentDidMount() {
      // this would fetch or connect to a store
      this.setState({ name: "Michael" });
    }

    render() {
      return ;
    }
  };

這是一個返回了入參為組件的普通函數

接著,我們需要把 Greeting 包裹到 Connect

const ConnectedMyComponent = Connect(Greeting);

這是一個強大的模式,它可以用來獲取數據和給定數據到任意 函數組件 中。

狀態提升 (State hoisting)

函數組件 沒有狀態 (就像名字暗示的一樣)。

事件是狀態的變化。

它們的數據需要傳遞給狀態化的父 容器組件

這就是所謂的「狀態提升」。

它是通過將回調從容器組件傳遞給子組件來完成的

class NameContainer extends React.Component {
  render() {
    return  alert(newName)} />;
  }
}

const Name = ({ onChange }) => (
   onChange(e.target.value)} />
);

Name 組件從 NameContainer 組件中接收 onChange 回調,并在 input 值變化的時候調用。

上面的 alert 調用只是一個簡單的演示,但它并沒有改變狀態

讓我們來改變 NameContainer 組件的內部狀態。

class NameContainer extends React.Component {
  constructor() {
    super();
    this.state = { name: "" };
  }

  render() {
    return  this.setState({ name: newName })} />;
  }
}

這個狀態 被提升 到了容器中,通過添加回調函數,回調中可以更新本地狀態。這就設置了一個很清晰邊界,并且使功能組件的可重用性最大化。

這個模式并不限于函數組件。因為函數組件沒有生命周期事件,你也可以在類組件中使用這種模式。

受控輸入 是一種與狀態提升同時使用時很重要的模式

(最好是在一個狀態化的組件上處理事件對象)

受控輸入 (Controlled input)

討論受控輸入的抽象并不容易。讓我們以一個不受控的(通常)輸入開始。

當你在瀏覽器中調整此輸入時,你會看到你的更改。 這個是正常的

受控的輸入不允許 DOM 變更,這使得這個模式成為可能。通過在組件范圍中設置值而不是直接在 DOM 范圍中修改

顯示靜態的輸入框值對于用戶來說并沒有什么用處。所以,我們從狀態中傳遞一個值到 input 上。

class ControlledNameInput extends React.Component {
  constructor() {
    super();
    this.state = { name: "" };
  }

  render() {
    return ;
  }
}

然后當你改變組件的狀態的時候 input 的值就自動改變了。

return (
   this.setState({ name: e.target.value })}
  />
);

這是一個受控的輸入框。它只會在我們的組件狀態發生變化的時候更新 DOM。這在創建一致 UI 界面的時候非常有用。

如果你使用 函數組件 做為表單元素,那就得閱讀 狀態提升 一節,把狀態轉移到上層的組件樹上。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/101366.html

相關文章

  • 前端資源系列(4)-前端學習資源分享&前端面試資源匯總

    摘要:特意對前端學習資源做一個匯總,方便自己學習查閱參考,和好友們共同進步。 特意對前端學習資源做一個匯總,方便自己學習查閱參考,和好友們共同進步。 本以為自己收藏的站點多,可以很快搞定,沒想到一入匯總深似海。還有很多不足&遺漏的地方,歡迎補充。有錯誤的地方,還請斧正... 托管: welcome to git,歡迎交流,感謝star 有好友反應和斧正,會及時更新,平時業務工作時也會不定期更...

    princekin 評論0 收藏0
  • 【搶先領】《React 學習之道》我們翻譯了一本最簡單,且最實用的 React 實戰教程……

    摘要:學習之道簡體中文版通往實戰大師之旅掌握最簡單,且最實用的教程。前言學習之道這本書使用路線圖中的精華部分用于傳授,并將其融入一個獨具吸引力的真實世界的具體代碼實現。完美展現了的優雅。膜拜的學習之道是必讀的一本書。 《React 學習之道》The Road to learn React (簡體中文版) 通往 React 實戰大師之旅:掌握 React 最簡單,且最實用的教程。 showIm...

    oneasp 評論0 收藏0
  • 程序員練級攻略(2018):前端性能優化和框架

    摘要:,谷歌給的一份性能指南和最佳實踐。目前而言,前端社區有三大框架和。隨后重點講述了和兩大前端框架,給出了大量的文章教程和相關資源列表。我認為,使用函數式編程方式,更加符合后端程序員的思路,而是更符合前端工程師習慣的框架。 showImg(https://segmentfault.com/img/bVbjQAM?w=1142&h=640); 這個是我訂閱 陳皓老師在極客上的專欄《左耳聽風》...

    VEIGHTZ 評論0 收藏0
  • 程序員練級攻略(2018):前端性能優化和框架

    摘要:,谷歌給的一份性能指南和最佳實踐。目前而言,前端社區有三大框架和。隨后重點講述了和兩大前端框架,給出了大量的文章教程和相關資源列表。我認為,使用函數式編程方式,更加符合后端程序員的思路,而是更符合前端工程師習慣的框架。 showImg(https://segmentfault.com/img/bVbjQAM?w=1142&h=640); 這個是我訂閱 陳皓老師在極客上的專欄《左耳聽風》...

    CoffeX 評論0 收藏0
  • 前端文檔收集

    摘要:系列種優化頁面加載速度的方法隨筆分類中個最重要的技術點常用整理網頁性能管理詳解離線緩存簡介系列編寫高性能有趣的原生數組函數數據訪問性能優化方案實現的大排序算法一怪對象常用方法函數收集數組的操作面向對象和原型繼承中關鍵詞的優雅解釋淺談系列 H5系列 10種優化頁面加載速度的方法 隨筆分類 - HTML5 HTML5中40個最重要的技術點 常用meta整理 網頁性能管理詳解 HTML5 ...

    jsbintask 評論0 收藏0

發表評論

0條評論

hzx

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<