オブジェクトの代わりにJSX
バベルはJSXがReact.createElementという名前のメソッド()の呼び出しに変換されて脱出します。
2つのコードの次のような効果は同じです。
const element = (
<h1 className="greeting">
Hello, world!
</h1>
);
const element = React.createElement(
'h1',
{className: 'greeting'},
'Hello, world!'
);
React.createElement()いくつかのバグを回避するため、この方法は、最初に確認し、次に同様の目的を以下の例を戻します。
// 注意: 以下示例是简化过的(不代表在 React 源码中是这样)
const element = {
type: 'h1',
props: {
className: 'greeting',
children: 'Hello, world'
}
};
このようなオブジェクトは、「要素に反応」と呼ばれています。それはあなたが画面に表示されるすべてのものを表しています。コンテンツデータオブジェクトを読み込むことによって構築DOMを反応させ、一貫性を維持します。
小道具は読み取り専用です
あなたは、独自の小道具を変更してはなりませんコンポーネントを宣言するために、関数やクラスを使用するかどうか。すべてのコンポーネントは、純粋な機能のような小道具としてそれらを使用する必要があります反応します。
トップダウンのデータフロー
親コンポーネントまたはサブアセンブリは、コンポーネントがステートフルまたはステートレスであり、そしてそれらは関数またはクラスとして定義されている成分を懸念すべきではないかどうかを知ることができません。
状態は、一般的に、ローカルまたはカプセル化と呼ばれている理由です。セットとそのコンポーネントを有することに加えて、他のコンポーネントにはアクセスできません。
これは、一般的に、トップダウンまたは単方向データフローと呼ばれています。いずれの状態は常に、すべてのコンポーネント、および任意のデータやUIの状態から派生のみのツリーの下のコンポーネントに影響を与えることができると確信しました。
コンポーネントのレンダリングを防ぎます
まれに、あなたはそれが他のコンポーネントをレンダリングされた場合でも、コンポーネントを非表示にすることがあります。この方法ではなく、その結果を実現することができるレンダリングのnullを返しレンダリングしてみましょう。
しかし、コンポーネントメソッドはnullを返し、コンポーネントのライフサイクルコールバックメソッドには影響しないレンダリング、ことに留意すべきです。
地位を強化
反応する状態は、アセンブリを完成するために、最も近い親から必要なデータまでのコンポーネントの状態データによって共有されます。これはと呼ばれる状態のアップグレード。
アプリケーションに反応する、任意の変数データべき単一に対応する「データソース」。一般的には、状態が最初にレンダリングする部品データを追加するために必要とされています。他のコンポーネントも、これらのデータを必要としている場合は、この場合、あなたは彼らの最も近い親コンポーネントからのデータにアップグレードすることができます。あなたは、アプリケーション内で上から下へのデータフローを維持するのではなく、さまざまなコンポーネントの状態を同期しようとすべきです。
継承の組み合わせVS
強力な組み合わせモデルと反応して、我々は、使用されるコンポーネント間のコードを再利用するために組み合わせではなく、継承を使用することをお勧めします。
包含関係
プロパティのサブ要素が出力に直接渡され、子供を使用
function FancyBorder(props) {
return (
<div className={'FancyBorder FancyBorder-' + props.color}>
{props.children}
</div>
);
}
function WelcomeDialog() {
return (
<FancyBorder color="blue">
<h1 className="Dialog-title">
Welcome
</h1>
<p className="Dialog-message">
Thank you for visiting our spacecraft!
</p>
</FancyBorder>
);
}
あまり一般的ものの、時にはあなたが代わりに合意された子供たちの独自のプロパティを使用することができ、その場合、アセンブリ内の複数の入口を、したいことがあります。
function SplitPane(props) {
return (
<div className="SplitPane">
<div className="SplitPane-left">
{props.left}
</div>
<div className="SplitPane-right">
{props.right}
</div>
</div>
);
}
function App() {
return (
<SplitPane
left={
<Contacts />
}
right={
<Chat />
} />
);
}
だから、それを継承しますか?
Facebookのサイトでは、当社が部品の何千も反応するが、それはどのような場合を発見していない使用しますが、継承を使用することをお勧めする必要があります。
プロパティとの組み合わせはあなたのために必要なコンポーネントのスタイルと動作から明らかな方法ですべての柔軟性とセキュリティを提供します。コンポーネントは、基本データ型、要素または機能反応を含む、任意の要素を受け入れることができることを思い出してください。
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は、これらの問題を回避するためのクラスとして定義されていますが、ほとんどの場合は問題ではありません。