Reactモード(中国語版)

14722 ワード

日本語版:https://reactpatterns.cn/オリジナル:https://reactpatterns.com
関数コンポーネント(Function component)
関数構成要素は、最も単純なものであり、多重化可能なコンポーネントを宣言する方法である.
彼らは簡単な関数です.
function Greeting() {
  return 
Hi there!
; }
最初のモダリティから属性セットを取得する.
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の特性です.
ES 2015版の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}!
; }
その3つの点(...)は、残りのすべての属性をrestPropsオブジェクトに割り当てる.
ところで、restPropsを使って何ができますか?
続けて…を見る.
JSXにおける属性展開(JSX spread atributes)
属性展開はJSXの中の一つの特性です.
オブジェクトの属性をJSXの属性に変換する文法です.
上記の属性解を参照してください.restPropsオブジェクトのすべての属性をdiv要素に拡散することができます.
function Greeting({ name, ...restProps }) {
  return 
Hi {name}!
; }
これはGrettingコンポーネントを非常に柔軟にする.
GettingコンポーネントDOM属性に伝達することによって、これらの属性が必ずdivにアップロードされると判断することができる.
非DOM属性をコンポーネントに渡すことを避ける.解約値は、 およびDOM/ を分離することができるので、人気があります.
function Greeting({ name, ...platformProps }) {
  return 
Hi {name}!
; }
結合解除属性と他の値(Merge destructured props with other values)
コンポーネントは抽象です.
良い抽象は拡張できる.
例えば、このコンポーネントはボタンにスタイルを追加するためにclass属性を使用する.
function MyButton(props) {
  return 

一般情况下这样做就够了,除非我们需要扩展其它的样式类

Delete...
この例ではbtndelete-btnに置き換える.
JSXの属性展開は先着順に敏感です.
拡散属性のclassNameは、コンポーネントのclassNameをカバーする.
私たちはこの2つの順序を変えることができますが、今のところclassNamebtnだけです.
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, "!"]}
配列をサブ要素とする(Aray 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)}
);
明らかに、1つの静的な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)
(私はこの名前の正確な呼び方が分かりません. : 、 、 ?)
ボタンはウェブアプリケーションでどこにでもあります.そして、すべてのボタンには一つのtype="button"の属性が必要です.

重复的写这些属性很容易出错。我们可以写一个高层组件来代理 props 到底层组件。

const Button = props =>
  

我们可以使用 Button 组件代替 button 元素,并确保 type 属性始终是 button。


// 
スタイルコンポーネント
これもプロキシコンポーネントであり、スタイルを処理するために使用されます.
もし私たちがボタンを持っているなら、それは「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コンポーネントは2つのサブコンポーネントの です.コンポーネントはいつまでも しないように えてくれます.
class HorizontalSplit extends React.Component {
  shouldComponentUpdate() {
    return false;
  }

  render() {
    
      
{this.props.leftSide}
{this.props.rightSide}
} }
セット(Continer component)
「 はデータを してサブアセンブリにレンダリングするだけです.」
これは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)
は、 なくとも の を たす です.
  • は、
  • として1つ の を け る.
  • は、
  • を します.
    のコンポーネントは ですか?
    すでに のコンポーネントを っているなら、これは されたコンポーネントだけで、 に まれます.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 ;
        }
      };
    これはコンポーネントに る の です.
    に、GreetingConnectに む があります.
    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インターフェースを する に に である.
    コンポーネントをフォーム として うなら、 を させ、 のコンポーネントツリーに を させます.