私はしばらく 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をインストールする方法
序文MySQL クエリは select コマンドを使用し、limit および offset パラメー...
この記事では、jQueryプラグインを使用してマインスイーパゲームを実装する2番目の記事を参考までに...
しばらく前にシステムを再インストールしましたが、バックアップを取っていなかったので、コンピューター上...
実験環境: MYSQL 5.7.22バイナリログを有効にするログ形式 MIXED実験プロセス: 1....
最近はWeb2.0という言葉をよく耳にしますが、Web2.0とは何でしょうか? Web 1.0 とど...
XiaobaiはVueについて学び、次にwebpackについて学び、そしてさまざまなものをインストー...
tomcat の解凍されたディレクトリを開くと、次のディレクトリ構造が表示されます。 1.Tomca...
序文皆さんはリモート サーバーで開発を行っており、MySQL の使用率はかなり高いはずです。コマンド...
1. まずシステムにmysqlがインストールされているかどうかを確認します rpm -qa | gr...
序文Oracle や SQL Server などのデータベースには、ストレージ エンジンが 1 つだ...
1. Get はサーバーからデータを取得するために使用され、Post はサーバーにデータを渡すために...
通常は ul、li を介して選択のデフォルト スタイルを変更して、実現をシミュレートします。このよう...
インストールインストールするには、次のコマンドを入力します。 // ネプ npm で react-r...
最近、あるプロジェクトのクライアントが、上部に 2 つのタブ メニューを配置することを要求しました。...
MySQLテーブルパーティショニングプログラムを変更する方法1. サブテーブルの実装の原則は次のとお...