Reactモード(中国語版)
14722 ワード
日本語版:https://reactpatterns.cn/オリジナル:https://reactpatterns.com
関数コンポーネント(Function component)
関数構成要素は、最も単純なものであり、多重化可能なコンポーネントを宣言する方法である.
彼らは簡単な関数です.
最後に必ずあなたのReactコンポーネントに戻ります.
解約値はJavaScriptの特性です.
ES 2015版のJavaScriptによる新仕様です.
だからあまり見かけないかもしれません.
文字通りの量赋の反転形式のようです.
これらのコンポーネントは以下のように同じです.
残りのパラメータというのは、このように見えます.
ところで、
続けて…を見る.
JSXにおける属性展開(JSX spread atributes)
属性展開はJSXの中の一つの特性です.
オブジェクトの属性をJSXの属性に変換する文法です.
上記の属性解を参照してください.
GettingコンポーネントDOM属性に伝達することによって、これらの属性が必ず
コンポーネントは抽象です.
良い抽象は拡張できる.
例えば、このコンポーネントはボタンにスタイルを追加するために
JSXの属性展開は先着順に敏感です.
拡散属性の
私たちはこの2つの順序を変えることができますが、今のところ
多くのタイプがReactのサブ要素として利用できます.
多くの場合、
文字列
配列をサブ要素とするのはよく見られます.
リストはどのようにReactに描かれていますか?
Reactコンポーネントは関数タイプのサブ要素をサポートしていません.
しかし、レンダリング属性は、コンポーネントを作成し、関数をサブ要素とすることができるモードである.
レンダリング属性(Render prop)
ここにはレンダリング・コールバック関数childrenを使用したコンポーネントがあります.
このように書いてもあまり役に立たないですが、入門の簡単な例として使えます.
このコンポーネントを使用するために、コンポーネントを呼び出したときに、サブ要素が入ってきます.このサブ要素は関数です.
サブアセンブリの転送(Children pass-through)
このコンポーネントは
(私はこの名前の正確な呼び方が分かりません.
ボタンはウェブアプリケーションでどこにでもあります.そして、すべてのボタンには一つの
これもプロキシコンポーネントであり、スタイルを処理するために使用されます.
もし私たちがボタンを持っているなら、それは「primary」を使ってスタイルにします.
関数コンポーネント(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...
この例ではbtn
をdelete-btn
に置き換える.JSXの属性展開は先着順に敏感です.
拡散属性の
className
は、コンポーネントのclassName
をカバーする.私たちはこの2つの順序を変えることができますが、今のところ
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, "!"]}
配列をサブ要素とする(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 ;
}
};
これはコンポーネントに る の です.
に、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インターフェースを する に に である.
コンポーネントをフォーム として うなら、 を させ、 のコンポーネントツリーに を させます.