私はしばらく react を書いてきましたが、その 99% の時間は state、prop、useState、useEffect について書いてきました。特に ref についてはよく知りません。数日前に要件を作成し、ref を使用して親コンポーネントから子コンポーネントの状態値を実装したいと思ったのですが、失敗しました。ref に関連するコンテンツを整理したいと思います。 refとは何か公式サイト紹介: 一般的な React データフローでは、props は親コンポーネントが子コンポーネントと対話する唯一の方法です。子コンポーネントを変更するには、新しいプロパティを使用して再レンダリングする必要があります。ただし、通常のデータ フローの範囲外でサブコンポーネントを強制的に変更する必要がある場合もあります。変更された子コンポーネントは、React コンポーネントまたは DOM 要素のインスタンスである可能性があります。どちらの場合も、React は ref を使用して dom またはコンポーネント インスタンスを取得するという解決策を提供します。 refの使い方DOM要素に配置するこれはrefの最も直接的な使用法である Demoクラスをエクスポートし、React.Componentを拡張します。 コンストラクタ(props) { スーパー(小道具) this.myRef = createRef() } コンポーネントマウント() { コンソールログ(this.myRef) } 与える() { <div ref={this.myRef}>test</div> を返します } } 印刷してrefが何であるか確認する ref.current は DOM 要素を取得するので、入力フォーカスなど、DOM 要素自体のいくつかの機能を実装できることがわかります。 Demoクラスをエクスポートし、React.Componentを拡張します。 コンストラクタ(props) { スーパー(小道具) this.myRef = createRef() } クリック時 = () => { this.myRef.current.focus() } 与える() { 戻る ( <div> <button onClick={this.onClick}>フォーカス</button> <input ref={this.myRef} /> </div> ) } } 公式ウェブサイトでは、ref コールバックの形式も提供されています。 Demoクラスをエクスポートし、React.Componentを拡張します。 コンストラクタ(props) { スーパー(小道具) this.myRef = null } クリック時 = () => { this.myRef.focus() } 与える() { 戻る ( <div> <button onClick={this.onClick}>フォーカス</button> <input ref={ele => this.myRef = ele} /> // ここでの ele は dom 要素です</div> ) } } クラスコンポーネントに配置する実際、コンポーネントはネイティブ DOM に似ています。コンポーネントも独自の UI といくつかの機能を持つ要素です。そのため、コンポーネントに ref を配置すると、コンポーネントの例を取得することもできます。 // 子コンポーネントクラス Child は React.Component を拡張します { コンストラクタ(props) { スーパー(小道具) この状態 = { 名前: 'xx' } } 与える() { <div>子要素 {this.state.name}</div> を返します。 } } Demoクラスをエクスポートし、React.Componentを拡張します。 コンストラクタ(props) { スーパー(小道具) this.myRef = createRef() } コンポーネントマウント() { コンソールログ(this.myRef) } 与える() { 戻る ( <子ref={this.myRef} /> ) } } 子コンポーネントのインスタンスを取得できるようになったので、子コンポーネントを操作できるようになります。例えば、記事の冒頭で述べたように、親コンポーネントで子コンポーネントのステータス値をいくつか取得したいとします。 クラスChildはReact.Componentを拡張します。 コンストラクタ(props) { スーパー(小道具) この状態 = { カウント: 0 } } クリック時 = () => { this.setState({count: this.state.count+1}) } 与える() { 戻り値 <button onClick={this.onClick}>クリック +1: {this.state.count}</button> } } Demoクラスをエクスポートし、React.Componentを拡張します。 コンストラクタ(props) { スーパー(小道具) this.myRef = createRef() } クリック時 = () => { console.log(this.myRef.current.state.count) // 子コンポーネントの状態値を取得します} 与える() { 戻る ( <div> <button onClick={this.onClick}>サブコンポーネントのクリック数を取得します</button> <Child ref={this.myRef} /> // ref は子コンポーネントのインスタンスを取得します</div> ) } } 値を取得できるので、関数を使用して子コンポーネントを変更することもできます。 クラスChildはReact.Componentを拡張します。 コンストラクタ(props) { スーパー(小道具) この状態 = { 名前: 'xx' } } 名前の変更 = () => { this.setState({name: 'ww'}) } 与える() { <div>子要素 {this.state.name}</div> を返します。 } } Demoクラスをエクスポートし、React.Componentを拡張します。 コンストラクタ(props) { スーパー(小道具) this.myRef = createRef() } クリック時 = () => { this.myRef.current.changeName() // 親コンポーネントが子コンポーネントに到達します} 与える() { 戻る ( <div> <button onClick={this.onClick}>子コンポーネントの状態を変更する</button> <子ref={this.myRef} /> </div> ) } } もちろん、この例は適切ではありません。親コンポーネントが子コンポーネントの状態を変更する場合は、状態を親コンポーネントに昇格させてから、それを子コンポーネントのプロパティとして渡す必要があります。 関数コンポーネントに配置するこれは、記事の冒頭で要件を記述したときに私が犯した間違いです。関数コンポーネントにはインスタンスがないため、Ref を関数コンポーネントに配置できません。 定数子 = () => { <div>子コンポーネント</div>を返します。 } エクスポートconstデモ = () => { const myRef = useRef() // 関数コンポーネント内でrefを作成できます 使用効果(() => { コンソールログ(myRef) }, []) return <Child ref={myRef} /> // ただし、関数コンポーネントに配置すると無効になります} 関数コンポーネントは ref を使用できないのですか? もちろんそんなことはありません、ハハ。関数コンポーネントを forwardRef でラップできます。 const Child = (props, ref) => { // パッケージ化後、元の props に加えて、ref も返されます <div ref={ref}>child component</div> // まだ dom にマウントする必要があります} const ProChild = React.forwardRef(Child) // 重要なポイントはここです export const Demo = () => { 定数 myRef = useRef() 使用効果(() => { コンソールログ(myRef) }, []) <ProChild ref={myRef} /> を返します。 } 公式サイトからのヒントは次のとおりです。 関数コンポーネントでも ref を使用できるため、関数コンポーネントを使用して親コンポーネントを実装し、子コンポーネントのデータを取得します。ただし、forwardRef でラップした後でも、ref を dom またはクラス コンポーネントにマウントする必要があることがわかります。データのみをマウントする場合は、useImperativeHandle も使用する必要があります。 const 子 = (props, ref) => { 定数[count, setCount] = useState(0) 命令型ハンドルを使用します( 参照、 () => ({ // これは外部参照に公開されるデータです getVal: ()=> count })、 [カウント]、 ) 定数onClick = () => { setCount(pre => pre+1) } 戻り値 <button onClick={onClick}>クリック +1: {count}</button> } const ProChild = React.forwardRef(Child) エクスポートconstデモ = () => { 定数 myRef = useRef() 定数onClick = () => { console.log(myRef.current.getVal()) // 子コンポーネントの値を取得します} return <><button onClick={onClick}>子コンポーネントのクリック数を取得します</button><ProChild ref={myRef} /></> } これまでのところ、要求を行う際に残っていた問題は解決されました✅ 要約する最後に、親コンポーネントが子コンポーネントの状態を取得するシナリオでは、一般的に状態昇格+コールバックで通信し、要求は最終的にこのように実装されることを強調する必要があります。 最初にrefを使用したかった理由は、状態が昇格した後、子コンポーネントの変更により親コンポーネントが再レンダリングされると考えましたが、レンダリングを起こさずにデータを取得したかっただけです。
以上がReact refの使い方の詳しい説明の内容です。React refの使い方についてさらに詳しく知りたい方は、123WORDPRESS.COM内の他の関連記事もぜひご覧ください! 以下もご興味があるかもしれません:
|
<<: MySQL における KEY、PRIMARY KEY、UNIQUE KEY、INDEX の違い
>>: Raspberry PiにDockerをインストールする方法
目次NFS サービスの概要NFS とは何ですか? NFS マウントの原則NFS サーバーはデータ転送...
Win10 で csv をエクスポートする方法は 2 つあります。1 つ目はツールを使用することです...
CentOS でカーネル モジュールを自動的にロードするには、/etc/sysconfig/modu...
必要な効果: 確認コードを送信するためにクリックした後、ボタンは無効になり、5 秒後に無効解除されま...
目次1. インストール2. vue2でEchartsを使用するmain.jsファイル内コンテナが与え...
目次序文Viteプロジェクトを作成する改修プロジェクトディレクトリの規則その他の構成序文毎日鳩、火ば...
問題を見つける上位の SQL ステートメントを取得すると、DB が大量のselect @@sessi...
コンテナの場合、最も単純なヘルスチェックはプロセス レベルのヘルスチェックであり、プロセスが稼働して...
この記事では、具体的な例を使用して、CentOS 7 から CentOS 8 にアップグレードする方...
この記事では、jQuery キャンバスを使用して QR コード付きのポスターを生成するための具体的な...
1. Flashプラグインパッケージのダウンロードアドレス: https://get.adobe.c...
MySQL では、LOAD_FILE() 関数はファイルを読み取り、その内容を文字列として返します。...
序文この記事では、主にライブラリ内のすべてのテーブルを返すMysql8.0ドライバgetTables...
目次起源環境情報トラブルシューティングのプロセス要約する起源顧客は CentOS をベースにしたカス...
/***************** * proc ファイルシステム***************...