それはどういう意味ですか…ReactJSXで休む


83

このReactRouter Dom v4の例を見るとhttps://reacttraining.com/react-router/web/example/auth-workflowPrivateRouteコンポーネントがこのような残りの小道具を分解していることがわかります

const PrivateRoute = ({ component: Component, ...rest }) => (
  <Route {...rest} render={props => (
    fakeAuth.isAuthenticated ? (
      <Component {...props}/>
    ) : (
      <Redirect to={{
        pathname: '/login',
        state: { from: props.location }
      }}/>
    )
  )}/>
)

私はそれが{ component: Component, ...rest }意味することを確信したい:

からprops、コンポーネントプロップを取得してから、他のすべてのプロップを取得し、名前propsをに変更restして、ルートrender関数に渡されるプロップの名前付けの問題を回避できるようにします。

私は正しいですか?


5
これは標準化されていませんが、github.com
tc39 /

回答:


156

申し訳ありませんが、私の最初の答えは(うまくいけばまだ有用な/追加のコンテキストを提供している間)あなたの質問に答えないことに気づきました。もう一度やり直します。

あなたが尋ねる:

私はそれが{ component: Component, ...rest }意味することを確信したい:

からpropsComponent小道具を取得してから、他のすべてを取得し、props名前propsをに変更して、Route関数に渡されるrest名前の問題を回避できるようにし ます。propsrender

あなたの解釈は完全に正しくありません。しかし、あなたの考えに基づくと、ここで起こっていることはある種のオブジェクトの破壊に相当するという事実を少なくとも知っているようです(詳細については、2番目の回答とコメントを参照してください)。

正確に説明するために、{ component: Component, ...rest }式を2つの別々の操作に分解してみましょう。

  1. 操作1:検索componentで定義されたプロパティprops:小文字のC creationCompleteコンポーネント)を、我々は呼ん状態で新しい場所に割り当てComponent:資本CのcreationCompleteコンポーネント)。
  2. 操作2:次に、オブジェクトに定義されている残りのすべてプロパティを取得し、propsと呼ばれる引数内に収集しますrest

重要な点は、名前propsをに変更しないことですrest。(また、「propsRouterender関数に渡される名前の問題を回避する」こととは関係ありません。)

rest === props;
// => false

オブジェクトで定義されたプロパティの残りの部分(したがって、引数の名前がそのようになっている理由)を、propsと呼ばれる新しい引数に単純にプルしますrest


使用例

これが例です。次のように定義されたオブジェクト `myObj`があると仮定します。
const myObj = {
  name: 'John Doe',
  age: 35,
  sex: 'M',
  dob: new Date(1990, 1, 1)
};

この例では、に示さpropsれているのと同じ構造(つまり、プロパティと値)を持っていると考えると役立つ場合がありますmyObj。それでは、次の代入を書いてみましょう。

const { name: Username, ...rest } = myObj

上記のステートメントは、2つの変数(または、おそらく定数)の宣言代入の両方に相当します。このステートメントは、次のように考えることができます。

name定義されたプロパティをmyObj取得し、その値を新しい変数に割り当てますUsername。その後、テイクは、他のどんなプロパティに定義されたmyObjすなわちagesexおよびdob)、変数我々の名に割り当てられた新しいオブジェクトにそれらを集めますrest

ロギングUsernamerestにこれconsoleを確認します。次のものがあります。

console.log(Username);
// => John Doe
console.log(rest);
// => { age: 35, sex: 'M', dob: Mon Jan 01 1990 00:00:00 GMT-0800 (PST) }

サイドノート

あなたは不思議に思うかもしれません:

componentプロパティの名前をComponent大文字の「C」に変更するだけで、プロパティを削除するという問題が発生するのはなぜですか。

ええ、それはかなり些細なようです。そして、それは標準的なReactの慣習ですが、そのフレームワークに関するFacebookのすべてのドキュメントがそのように書かれているのには理由があります。つまり、JSXでレンダリングされたカスタムコンポーネントを活用すること自体は、必要以上に実践的ではありません。React、より適切には、JSXでは大文字と小文字が区別されます。大文字の最初の文字なしで挿入されたカスタムコンポーネントは、DOMにレンダリングされません。これは、Reactがカスタムコンポーネントを識別するためにそれ自体を定義した方法です。したがって、プルオフされたcomponentプロパティの名前を追加で変更しなかっpropsComponent場合、<component {...props} />式は正しくレンダリングされませんでした。


5
私たち初心者のための素晴らしい外植!
user27635 5719

13

それはあなたがprops単一の簡潔な表現であなたのすべてを「広げる」ことを可能にします。たとえばpropsPrivateRouteコンポーネントが受信したものが次のようになっていると仮定します。

// `props` Object:
{
  thing1: 'Something',
  thing2: 'Something else'
}

あなたは(これらの項目から外れ、さらに手に望んでいた場合、すなわちthing1thing2)ネストされたまで<Component />、タグ、あなたが精通していなかったオブジェクトのスプレッド構文、あなたが書くかもしれません。

<Component
  thing1={ props.thing1 }
  thing2={ props.thing2 } />

しかし、{ ...props }構文は、あなたができるようにすることで、このような冗長性を排除広め、あなたのprops1があります同じようにオブジェクトを広める値の配列(例えば[...vals])。つまり、以下のJSX式と上記のJSX式はまったく同じです。

<Component { ...props } />

1
関連している間は、JSXのspread構文をrestプロパティと混在させないでください。
Felix Kling 2017

3
「これにより、すべての小道具を1つの簡潔な表現で「広げる」ことができます。」そうではありません。...restin{ component: Component, ...rest } 、オブジェクト内の他のすべてのプロパティを収集しますrest。問題は、...restではなく、についてです{...props}
Felix Kling 2017

Felixが指摘しているように、JSXの(非標準の)オブジェクトspread演算子と、ECMAScript2015仕様で定義されているrest_ / _spread演算子には違いがあります。一つには、のようなものを書き込もうとし{ ...myObj }た環境を非反応するには(例えば、ブラウザコンソール)がスローされますSyntaxError。それにもかかわらず、ES6のrest _ / _ Spreadは、JSXのオブジェクトスプレッドを考えるための有用な概念フレームワークを提供します。
isenrichO 2017

4

簡単にしましょう。JavaScriptでは、「キー:値」のペアが同じで obj={account:account}ある場合、はと同じobj={account}です。したがって、親から子コンポーネントに小道具を渡す場合:

const Input = ({name,label,error, ...rest}) => {
  return (
    <div className="form-group">
      <label htmlFor={name}>{label}</label>
      <input
        {...rest}
        autoFocus
        name={name}
        id={name}
        className="form-control"
        aria-describedby="emailHelp"
      />
    </div>
  );
};
export default Input;

残りの小道具を次のように渡します。

label={label} placeholder={placeholder} type={type}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.