JSXの深さ
本質的には、JSXだけ糖衣構文はReact.createElement(コンポーネント、小道具、...子供)の方法のために提供します。
例えば:
<MyButton color="blue" shadowSize={2}>
Click Me
</MyButton>
次のようにコンパイルします。
React.createElement(
MyButton,
{color: 'blue', shadowSize: 2},
'Click Me'
)
ノー子孫場合は、自己終了タグを使用することもできます。
<div className="sidebar" />
次のようにコンパイルします。
React.createElement(
'div',
{className: 'sidebar'},
null
)
そのため、あなたはJSXを使用する必要があります。
- 宣言する必要があります反応します。この方法は、コンパイルした後React.createElement JSXを起動されているので、あなたは最初にあなたのコード内でJSX変数に反応宣言する必要があります。
- 指定された要素の型を反応させます。タグはJSX成分を反応させる上部ケースの始まりを示し、これらのラベルは、同じ名前と参照の変数にコンパイルされ、そして場合要素タイプが表す小文字で始まる内蔵コンポーネント、等
または 。
使用の種類を確認してくださいPropTypes
あなたはデータが有効である受け取ることを保証するために使用することができ、検証のセットを含むPropTypes。あなたがプロパティに無効な値を渡すと、JavsScriptコンソールは警告を出力します。パフォーマンス上の理由から、propTypesだけ開発モードでチェックします。
次異なるバリデータを使用する例であります:
import PropTypes from 'prop-types';
MyComponent.propTypes = {
// 你可以将属性声明为以下 JS 原生类型
optionalArray: PropTypes.array,
optionalBool: PropTypes.bool,
optionalFunc: PropTypes.func,
optionalNumber: PropTypes.number,
optionalObject: PropTypes.object,
optionalString: PropTypes.string,
optionalSymbol: PropTypes.symbol,
// 任何可被渲染的元素(包括数字、字符串、子元素或数组)。
optionalNode: PropTypes.node,
// 一个 React 元素
optionalElement: PropTypes.element,
// 你也可以声明属性为某个类的实例,这里使用 JS 的
// instanceof 操作符实现。
optionalMessage: PropTypes.instanceOf(Message),
// 你也可以限制你的属性值是某个特定值之一
optionalEnum: PropTypes.oneOf(['News', 'Photos']),
// 限制它为列举类型之一的对象
optionalUnion: PropTypes.oneOfType([
PropTypes.string,
PropTypes.number,
PropTypes.instanceOf(Message)
]),
// 一个指定元素类型的数组
optionalArrayOf: PropTypes.arrayOf(PropTypes.number),
// 一个指定类型的对象
optionalObjectOf: PropTypes.objectOf(PropTypes.number),
// 一个指定属性及其类型的对象
optionalObjectWithShape: PropTypes.shape({
color: PropTypes.string,
fontSize: PropTypes.number
}),
// 你也可以在任何 PropTypes 属性后面加上 `isRequired`
// 后缀,这样如果这个属性父组件没有提供时,会打印警告信息
requiredFunc: PropTypes.func.isRequired,
// 任意类型的数据
requiredAny: PropTypes.any.isRequired,
// 你也可以指定一个自定义验证器。它应该在验证失败时返回
// 一个 Error 对象而不是 `console.warn` 或抛出异常。
// 不过在 `oneOfType` 中它不起作用。
customProp: function(props, propName, componentName) {
if (!/matchme/.test(props[propName])) {
return new Error(
'Invalid prop `' + propName + '` supplied to' +
' `' + componentName + '`. Validation failed.'
);
}
},
// 不过你可以提供一个自定义的 `arrayOf` 或 `objectOf`
// 验证器,它应该在验证失败时返回一个 Error 对象。 它被用
// 于验证数组或对象的每个值。验证器前两个参数的第一个是数组
// 或对象本身,第二个是它们对应的键。
customArrayProp: PropTypes.arrayOf(function(propValue, key, componentName, location, propFullName) {
if (!/matchme/.test(propValue[key])) {
return new Error(
'Invalid prop `' + propFullName + '` supplied to' +
' `' + componentName + '`. Validation failed.'
);
}
})
};
プロパティデフォルト
class Greeting extends React.Component {
render() {
return (
<h1>Hello, {this.props.name}</h1>
);
}
}
// 为属性指定默认值:
Greeting.defaultProps = {
name: 'Stranger'
};
// 渲染 "Hello, Stranger":
ReactDOM.render(
<Greeting />,
document.getElementById('example')
);
defaultPropsは、特に断りのない限り、初期値が存在し、親コンポーネントの場合に確保するthis.props.name。DefaultProps型チェックは、割り当て後、型チェックはまた、上記defaultPropsで適用される起こります。
参考文献&DOM
参考DOM要素を追加します。
特殊なプロパティを追加するコンポーネントのいずれかをサポートするように反応します。ref属性は、コンポーネントがロードまたはアンロードされたときに即座に実行されるコールバック関数を受け付けます。
HTML属性要素refに追加すると、DOM要素の基礎となる参照コールバックは、パラメータとして受け取りました。例えば、次のコードは、DOMノードの参照REFコールバックを格納するために使用されます。
class CustomTextInput extends React.Component {
constructor(props) {
super(props);
this.focus = this.focus.bind(this);
}
focus() {
// 直接使用原生 API 使 text 输入框获得焦点
this.textInput.focus();
}
render() {
// 使用 `ref` 的回调将 text 输入框的 DOM 节点存储到 React
// 实例上(比如 this.textInput)
return (
<div>
<input
type="text"
ref={(input) => { this.textInput = input; }} />
<input
type="button"
value="Focus the text input"
onClick={this.focus}
/>
</div>
);
}
}
あなたはnullを渡されますアンインストールすると、DOM要素渡されたrefのコールバック関数をロード中にアセンブリを反応させます。
コンポーネントクラスのRefを追加
カスタムコンポーネントのref属性は、クラス宣言を使用する場合、REFコールバックが受信されたインスタンスがすでにロードされて反応します。
そして、機能コンポーネント参考文献
彼らはインスタンスを持っていないため、機能部品にref属性を使用することはできません。しかし、あなたは、それがクラスDOM要素または構成要素を指すように、refの内部の機能コンポーネントを使用することができます。
親ノード・アセンブリは、DOMさらされます
まれなケースでは、子ノードにアクセスするために、親コンポーネントからDOMノードにすることもできます。この場合、我々は、子ノード上の特定のプロパティへの露出をお勧めします。関数は、子ノードの属性を取得し、ref属性としてDOMノードに接続します。これは、参考文献、コールバック子孫DOMノードへのミドルウェアによって親を可能にします。
例えば:
function CustomTextInput(props) {
return (
<div>
<input ref={props.inputRef} />
</div>
);
}
class Parent extends React.Component {
render() {
return (
<CustomTextInput
inputRef={el => this.inputElement = el}
/>
);
}
}
このモデルのもう一つの利点は、それが深いもたらすことができるということです。層は、それらの子孫の親コンポーネントアセンブリDOMノードへのアクセスを可能にする、小道具プロパティを介して送信されてもよいです。
注意を払います
インライン関数それが更新中に2回呼び出されます方法の定義内REFコールバックは、最初の引数がnullの場合、パラメータは、DOM要素です。関数は、各レンダリングの新しいインスタンスを作成するためです。そのため、古い参照をクリーンアップし、新しいものを設定する必要が反応します。ところで結合関数コールバックrefは、これらの問題を回避するためのクラスとして定義されていますが、ほとんどの場合は問題ではありません。
和解(協調アルゴリズム)
DOMを更新するために使用するアルゴリズムを反応させます。2つの仮定に基づいて、それはO(N)アルゴリズムのヒューリスティックを実装します。
- 要素の二つの異なる種類が異なるツリーを生成します。
- レンダラによってに含ま
key
概略的サブ要素が安定であり得ることができる不動産開発。
異なる種類の要素
2つのツリーを比較すると、ルートノードが最初の二つを比較して反応します。たびルート要素の異なる種類が存在するが、古い木をアンインストールし、新しいツリーを再構築するために反応します。
ツリーがアンロードされると、古いDOMノードが破壊されます。成分としてはcomponentWillUnmount()メソッドを受信します。新しいツリーを構築する場合、新しいDOMノードがDOMに挿入されています。成分としてはcomponentWillMount()とそれに続くcomponentDidMount()を受けました。古い木についてのすべての状態は破棄されます。
例えば、比較:
<div>
<Counter />
</div>
<span>
<Counter />
</span>
これは、古いカウンターを破壊し、新しいノードを再インストールします。
同じタイプのDOM要素
同じタイプの2つの要素を比較すると、DOMを反応させるのプロパティが観察されます両方反応して、唯一の属性変更を同じ基本DOMノードを維持し、更新されます。(例えば、クラス名、スタイルなどを変更します)
DOM要素を処理した後、再帰的にその子を反応します。
再帰的な子ノード
デフォルトの時間。子供が再帰的にDOMノードをノードすると、2つのだけの子ノードを再帰的に同じ時点でリストアップ反応し、同時に変化が発生しません。
子ノードの最後に要素を追加する場合、例えば、ウェル2つのツリーを遷移:
<ul>
<li>first</li>
<li>second</li>
</ul>
<ul>
<li>first</li>
<li>second</li>
<li>third</li>
</ul>
反応は、2つのツリーに一致します。
ときにネイティブ実装、スタートは、要素のプロパティを挿入することがより困難になります。例えば、2つのツリーの変換の効果は比較的劣っています。
<ul>
<li>Duke</li>
<li>Villanova</li>
</ul>
<ul>
<li>Connecticut</li>
<li>Duke</li>
<li>Villanova</li>
</ul>
それぞれの子ノードを調整し反応するのではなく、そのまま意識します
キー
この問題を解決するために、キー属性をサポートして反応します。子ノードのキーがある場合は、ツリーと子ノードの新しいツリーの元の子ノードを一致させるためにキーを使用して反応します。例えば、サンプルは、高効率になる前に、ツリーの変換効率を向上させるための鍵:
<ul>
<li key="2015">Duke</li>
<li key="2016">Villanova</li>
</ul>
<ul>
<li key="2014">Connecticut</li>
<li key="2015">Duke</li>
<li key="2016">Villanova</li>
</ul>
今「2014」との重要な要素を知って反応し、新規であり、「2015」と「2016」とだけ動く重要な要素。
バランス
満たされていないの背後にあると仮定すると、ヒューリスティックなアルゴリズムに依存しているリアクトので、その性能は影響を受けることになります。
- アルゴリズムは、子要素の異なるコンポーネントタイプを一致させようとすることはできません。あなたは2つの非常に類似した出力交流成分の種類を見つけた場合、あなたはそれと同じタイプにしたいかもしれません。実際には、我々は、これが問題ではないことがわかりました。
- キーは、安定した予測可能、かつユニークでなければなりません。(に似た不安定な鍵
Math.random()
の生成)コンポーネントインスタンスの数が多いと性能劣化及び状態サブアセンブリの損失ように、不要な再構成DOMノードを引き起こすであろう。
ポータル
ポータルは、コンポーネントアプローチ以外の親DOMノードへの良好なレンダリング子ノードを提供しています。
ReactDOM.createPortal(child, container)
最初のパラメータ(子供)は、任意の子要素は、要素、文字列や破片をレンダリングすることができる反応します。第二のパラメータ(コンテナ)は、DOM要素です。
使い方
あなたは方法はアセンブリからの要素、組立要素最も近い親要素からのみDOMノードを返しレンダリングする際に一般的に言えば、
render() {
// React mounts a new div and renders the children into it
return (
<div>
{this.props.children}
</div>
);
}
しかし、時にはそれがDOMノードの異なる位置に挿入されているにも有用です。
render() {
// React does *not* create a new div. It renders the children into `domNode`.
// `domNode` is any valid DOM node, regardless of its location in the DOM.
return ReactDOM.createPortal(
this.props.children,
domNode,
);
}
代表的なポータルユースケースのために親コンポーネントがあふれていたときです:隠されたまたはz-インデックススタイルをしていますが、そのコンテナの視覚的サブアセンブリ「ジャンプ(脱出)」にできるようにする必要があります。たとえば、ダイアログボックス、ホバーカードおよびプロンプトボックス。
イベントのためにポータルバブリング
ポータルは、DOMツリー内のどこにでも置くことができますが、彼らの行動の他の側面と一致し、通常の動作は、子ノードを反応させるのが。コンテキスト特性が正常に前と同じように働くことができるような、関係なく、ポータルは依然として存在しているので、その子ノードは、ポータルであるかどうかのは、DOMツリー内の位置に関係なく、木を反応します。
これは、イベントバブリングを含んでいます。ポータル内からトリガするイベントは、常に祖先ツリーに反応含まれてバブリングます。