React | 7. ref:DOMに名前を付ける


-HTMLでidを使用してDOMに名前を付けるように、応答項目の内部でDOMに名前を付ける方法があります.→ ref(reference)
反応素子でidを無効にしますか?
使用できますが、同じコンポーネントを複数回使用する場合、HTMLではDOMのidが一意でなければなりません.この場合、重複idを持つ複数のDOMが生成されます.→誤用!refはグローバル範囲で動作せず、素子内部でのみ動作するため、このような問題は発生しない.
refはどんな場合に使うべきですか?
特定のDOMで動作する必要がある場合はrefを使用します.→具体的にはDOMに直接触れなければならない場合に使用する.
1.サンプル構成部品の作成
/* ValidationSample.css */

.success {
  background-color: lightgreen;
}

.failure {
  background-color: lightcoral;
}
//ValidationSample.js

import React, { Component } from "react";
import "../css/ValidationSample.css"; //css를 import한다.

class ValidationSample extends Component {
  state = {
    password: "",
    clicked: false,
    validated: false,
  };

  handleChange = (e) => {
    this.setState({
      password: e.target.value,
    });
  };

  handleButtonClick = () => {
    this.setState({
      clicked: true,
      validated: this.state.password === "0000",
    });
  };
  render() {
    return (
      <div>
        <input
          type="password"
          value={this.state.password}
          onChange={this.handleChange}
          className={
            this.state.clicked
              ? this.state.validated
                ? "success"
                : "failure"
              : ""
          }
        ></input>
        <button onClick={this.handleButtonClick}>검증하기</button>
      </div>
    );
  }
}

export default ValidationSample;
  • input:onChangeイベント発生→handleChange更新状態のパスワード値を呼び出す.
  • button:onClickイベント発生→handleButtonClickを呼び出し、クリック値を真値、検証値を検証結果に設定します.
  • inputのclassName値は、ボタンを押す前に空の文字列を渡し、ボタンを押すと検証結果に基づいて成功値または失敗値を設定します.
  • 2.DOMを使用する必要があります
    stateを使用すると、必要な機能が実現されますが、stateだけで解決できない機能もあります.
  • フォーカス特定入力周期
  • 操作
  • スクロールバー
  • Canvas要素に描画、例えば
  • この場合はDOMに直接アクセスしなければならず,そのためにrefを直接使用する.
    refの使用
    refの使い方は2つあります.
    1.コールバック関数によるrefの設定
    refを作成する最も基本的な方法はコールバック関数を使用することです.refというコールバック関数をrefを追加したい要素に渡します.このコールバック関数はref値をパラメータとして渡します.次に、関数内部からパラメータとして受信したrefを要素のメンバー変数に設定します.
    <input ref = {(ref) => {this.input = ref}} />
    これならこれへInputとは、input要素のDOMを指す.refの名前は任意に指定できます.DOMタイプに関係なく、this.superman = refのように勝手に指定します.
    2.createRefでrefを設定する
    refを作成する別の方法は、reactionに組み込まれているcreateRefという関数を使用することです.
    //RefSample.js
    
    import React, { Component } from "react";
    
    class RefSample extends Component {
      input = React.createRef(); // 1. createRef 함수 사용, 멤버 변수로 React.crateRef()를 담아 줌
    
      handleFocus = () => {
        this.input.current.focus(); // 3. ref를 설정해 준 DOM에 접근
      };
      render() {
        return (
          <div>
            <input ref={this.input}></input> // 2. 멤버 변수를 ref props로 넣어 줌
          </div>
        );
      }
    }
    
    export default RefSample;
  • createRefを使用してrefを作成するには、まず構成部品の内部でメンバー変数として反応させます.createRef()が含まれます.
  • 対応するメンバー変数をref propsとしてrefしたい要素に入れると、ref設定が完了します.
  • を設定した後、refを設定するDOMにアクセスするには、次の手順に従います.input.現在のクエリを実行します.コールバック関数を使用する場合との違いは、後の部分にあります.電流を入れます.
  • 3.応用
    ValidationSample構成部品は次のとおりです.
  • input要素をクリックすると、テキストカーソルがフォーカスして点滅します.
  • ボタンを押すと、フォーカスはボタンに移り、左側のinput要素のテキストカーソルは表示されなくなります.
  • コールバック関数を使用して、→ボタンを押すと、コードを書き、フォーカスを自動的に入力端に回します!
  • import React, { Component } from "react";
    import "../css/ValidationSample.css";
    
    class ValidationSample extends Component {
      state = {
        password: "",
        clicked: false,
        validated: false,
      };
    
      handleChange = (e) => {
        this.setState({
          password: e.target.value,
        });
      };
    
      handleButtonClick = () => {
        this.setState({
          clicked: true,
          validated: this.state.password === "0000",
        });
        this.input.focus(); // input에 포커스를 준다
      };
      render() {
        return (
          <div>
            <input
              ref={(ref) => (this.input = ref)} // 콜백 함수를 사용하여 ref 설정
              type="password"
              value={this.state.password}
              onChange={this.handleChange}
              className={
                this.state.clicked
                  ? this.state.validated
                    ? "success"
                    : "failure"
                  : ""
              }
            ></input>
            <button onClick={this.handleButtonClick}>검증하기</button>
          </div>
        );
      }
    }
    
    export default ValidationSample;
  • inputにrefを追加
  • ボタンonClickイベントコードの変更
  • 構成部品にrefを追加するには
    反応器において、素子はrefを有することもできる.主にコンポーネントの外部でコンポーネント内部のDOMを使用するために使用されます.素子にrefを追加する方法は、DOMにrefを追加する方法と同じです.
    1.使用方法
    <MyComponent
        ref={(ref) => {
          this.myComponent = ref;
        }}
      />;
    MyComponent内部のメソッドやメンバー変数にもアクセスできます.すなわち,内部のrefにアクセスできる.(例えばmyComponent、handleClick、myComponent、inputなど)

  • 親構成部品でバーを下にスクロールします.
    スクロールバーを持つ構成部品の作成→構成部品にrefを掛ける→refを使用して構成部品の内部メソッドを呼び出す
  • 2.構成部品ファイルの作成
    構成部品ファイルの作成
    //ScollBox.js
    
    import React, { Component } from "react";
    
    class ScrollBox extends Component {
      render() {
        const style = {
          border: "1px solid black",
          height: "300px",
          width: "300px",
          overflow: "auto",
          position: "relative",
        };
    
        const innerStyle = {
          width: "100%",
          height: "650%",
          background: "linear-gradient(white, black)",
        };
        return (
          <div
            style={style}
            ref={(ref) => {
              this.box = ref;
            }}
          >
            <div style={innerStyle} />
          </div>
        );
      }
    }
    
    export default ScrollBox;
  • JSXの行内スタイル構文を使用してスクロールボックスを作成します.
  • トップクラスDOMにrefを追加します.
  • 3.構成部品の作成方法
    スクロールバーを構成部品の下部に下げる方法を作成します.JavaScriptを使用してバーを下にスクロールする場合、DOMノードには次の値があります.
  • スクロール上部:垂直スクロールバー位置(0~350)
  • スクロール高さ:スクロール付きシャーシのdiv高さ(650)
  • クライアントHeight:スクロール可能なシャーシ高さ(300)
  • import React, { Component } from "react";
    
    class ScrollBox extends Component {
      scrollToBottom = () => { // 스크롤 바를 아래로 내리기 위한 코드
        const { scrollHeight, clientHeight } = this.box; // 비구조화 할당 문법 사용
        // const scrollHeight = this.box.scrollHeight;
        // const clientHeight = this.box.cliengHeight;
        this.box.scrollTop = scrollHeight - clientHeight;
      };
      render() {
        const style = {
          border: "1px solid black",
          height: "300px",
          width: "300px",
          overflow: "auto",
          position: "relative",
        };
    
        const innerStyle = {
          width: "100%",
          height: "650%",
          background: "linear-gradient(white, black)",
        };
        return (
          <div
            style={style}
            ref={(ref) => {
              this.box = ref;
            }}
          >
            <div style={innerStyle} />
          </div>
        );
      }
    }
    
    export default ScrollBox;
    スクロールバーを一番下に下げて、遠くのscrollHeightからclientHeightの高さを引けばいいです.
    4.構成部品にrefを追加し、内部メソッドを使用する
    アプリケーションコンポーネントで、ScrollBoxにrefを追加してボタンを作成し、ScrollBoxコンポーネントのscrollToBottomメソッドを実行するコードを作成します.
    //App.js
    
    import React, { Component } from "react";
    import "./App.css";
    import ScrollBox from "./components/ScrollBox";
    
    class App extends Component {
      render() {
        return (
          <div>
            <ScrollBox ref={(ref) => (this.scrollBox = ref)}></ScrollBox>
            <button onClick={() => this.scrollBox.scrollToBottom()}>
              맨 밑으로
            </button>
          </div>
        );
      }
    }
    
    export default App;
    App.jsコードを関数型素子に置き換えるとエラーが発生します.理由を調べることで、関数型素子でrefの使用を制限できます.次の正式なドキュメントを確認します.
    https://reactjs-kr.firebaseapp.com/docs/refs-and-the-dom.html
    整理する
  • コンポーネント内でDOMに直接アクセスする必要がある場合はrefを使用しますが、refを必要とせずに必要な機能を実現できるかどうかを考慮する必要があります.
  • 異なるコンポーネント間のデータ交流はrefを使用しません!もちろんいいですが、エレメントにrefを追加して他のエレメントに渡すことができます...別の構成部品からrefに渡される構成部品を実行する方法...→複雑でメンテナンスできない.コンポーネント間でデータを交換する場合は、常にデータを親、子ストリームとして交流します.後で、RidexまたはContext APIによる効率的なコミュニケーションについて学習します.
  • 関数型素子でrefを使用することは学習されていない.関数型素子はuseRefというHook関数を用いる.React.createRefに似ています.