ReactでDOM要素にアクセスする方法は?Reactのdocument.getElementById()と同等のものは何ですか


203

react.jsで特定のバーを選択するにはどうすればよいですか?

これは私のコードです:

var Progressbar = React.createClass({
    getInitialState: function () {
        return { completed: this.props.completed };
    },
    addPrecent: function (value) {
        this.props.completed += value;
        this.setState({ completed: this.props.completed });
    },

    render: function () {

        var completed = this.props.completed;
        if (completed < 0) { completed = 0 };


        return (...);
    }

このReactコンポーネントを使用したい:

var App = React.createClass({
    getInitialState: function () {

        return { baction: 'Progress1' };
    },
    handleChange: function (e) {
        var value = e.target.value;
        console.log(value);
        this.setState({ baction: value });
    },
    handleClick10: function (e) {
        console.log('You clicked: ', this.state.baction);
        document.getElementById(this.state.baction).addPrecent(10);
    },
    render: function () {
        return (
            <div class="center">Progress Bars Demo
            <Progressbar completed={25} id="Progress1" />
                <h2 class="center"></h2>
                <Progressbar completed={50} id="Progress2" />
                <h2 class="center"></h2>
                <Progressbar completed={75} id="Progress3" />
                <h2 class="center"></h2>
                <span>
                    <select name='selectbar' id='selectbar' value={this.state.baction} onChange={this.handleChange}>
                        <option value="Progress1">#Progress1</option>
                        <option value="Progress2">#Progress2</option>
                        <option value="Progress3">#Progress3</option>
                    </select>
                    <input type="button" onClick={this.handleClick10} value="+10" />
                    <button>+25</button>
                    <button>-10</button>
                    <button>-25</button>
                </span>
            </div>
        )
    }
});

handleClick10関数を実行して、選択したプログレスバーの操作を実行したいのですが。しかし、私が得る結果は:

 You clicked:  Progress1
 TypeError: document.getElementById(...) is null

react.jsで特定の要素を選択するにはどうすればよいですか?

回答:


214

これを指定するには、 ref

編集:機能コンポーネントを備えたreact v16.8.0では、useRefを使用して参照を定義できます。機能コンポーネントでrefを指定するときは、React.forwardRefを使用してrefを使用useImperativeHandleするDOM要素に転送し、機能コンポーネント内から特定の機能を公開する必要があることに注意してください。

例:

const Child1 = React.forwardRef((props, ref) => {
    return <div ref={ref}>Child1</div> 
});

const Child2 = React.forwardRef((props, ref) => {
    const handleClick= () =>{};
    useImperativeHandle(ref,() => ({
       handleClick
    }))
    return <div>Child2</div> 
});
const App = () => {
    const child1 = useRef(null);
    const child2 = useRef(null);

    return (
        <>
           <Child1 ref={child1} />
           <Child1 ref={child1} />
        </>
    )
}

編集:

では16.3+が反応、使用をReact.createRef()ご参照を作成するには:

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.myRef = React.createRef();
  }
  render() {
    return <div ref={this.myRef} />;
  }
}

要素にアクセスするには、以下を使用します。

const node = this.myRef.current;

React.createRef()を使用するためのDOC


編集

ただし、文字列参照にはいくつかの問題があり、レガシーと見なされており、将来のリリースのいずれかで削除される可能性があるため、facebookはこれを推奨していません。

ドキュメントから:

レガシーAPI:文字列参照

以前にReactを使用したことがある場合は、ref属性が「textInput」などの文字列であり、DOMノードにthis.refs.textInputとしてアクセスする古いAPIに慣れているかもしれません。文字列参照にはいくつかの問題があり、レガシーと見なされており、将来のリリースのいずれかで削除される可能性があるため、これはお勧めしません。現在this.refs.textInputを使用して参照にアクセスしている場合は、代わりにコールバックパターンをお勧めします。

React 16.2以前で推奨される方法は、コールバックパターンを使用することです。

<Progressbar completed={25} id="Progress1" ref={(input) => {this.Progress[0] = input }}/>

<h2 class="center"></h2>

<Progressbar completed={50} id="Progress2" ref={(input) => {this.Progress[1] = input }}/>

  <h2 class="center"></h2>

<Progressbar completed={75} id="Progress3" ref={(input) => {this.Progress[2] = input }}/>

コールバックを使用するためのDOC


古いバージョンでも、以下のような文字列を使用して定義された参照を反応させます

<Progressbar completed={25} id="Progress1" ref="Progress1"/>

    <h2 class="center"></h2>

    <Progressbar completed={50} id="Progress2" ref="Progress2"/>

      <h2 class="center"></h2>

    <Progressbar completed={75} id="Progress3" ref="Progress3"/>

要素を取得するには、次のようにします

var object = this.refs.Progress1;

次のthisようなarrow関数ブロック内で使用することを忘れないでください。

print = () => {
  var object = this.refs.Progress1;  
}

等々...


5
Facebookはこのアプローチを推奨していません。こちらをご覧くださいfacebook.github.io/react/docs/refs-and-the-dom.html
Dmitry

4
@dmitrymar上記のページを見るとわかるように、v15.4.2以降向けに書かれていると思いますが、これは私が回答を書いたときに以前はなかったようです。とにかく、正しいアプローチで回答を編集しました
Shubham Khatri 2017

2
@MattSidor、編集してくれてありがとう、あなたは時間を節約してくれました:-)
Shubham Khatri

ええと、必要なコンポーネントが別のクラスのインスタンスである場合など、「this」を介してアクセスできない場合はどうでしょうか。(つまり、親コンポーネント内の別の子反応コンポーネント)
akshay kishore

@akshaykishore別の名前であるinnerRefを使用して参照を渡し、必要なコンポーネントに渡す必要があります
Shubham Khatri

37

react使用する必要がある要素を取得するにはref、関数内でReactDOM.findDOMNodeメソッド。

しかし、私がもっとやりたいのは、イベント内でrefを呼び出すことです

<input type="text" ref={ref => this.myTextInput = ref} />

これはあなたが理解するのに役立ついくつかの良いリンクです。


2
これはこれを行う正しい方法です。これにより、オブジェクト/クラスの要素への参照が、this.myTextInputアクセスに使用できるように追加されます。
Sam Parmenter 2017

1
動的に作成された要素でこれを行うにはどうすればよいですか?
Sagar Kodte

呼び出しReact.findDOMNodeは私を与えるreact__WEBPACK_IMPORTED_MODULE_0___default.a.findDOMNode is not a function
ジェームズプーローズ

@JamesPouloseを使用すると、厳密モードで実行していないことを確認できます。reactでは、厳密モードでの使用React.findDOMNodeが許可されないためです。
Limpuls

12

交換できます

document.getElementById(this.state.baction).addPrecent(10);

this.refs[this.state.baction].addPrecent(10);


  <Progressbar completed={25} ref="Progress1" id="Progress1"/>

3
動的に作成された要素でこれを行うにはどうすればよいですか?
Sagar Kodte

1

ReactはJSXコードを使用してHTMLを作成するため、documment.querySelectorやgetElementByIdなどの規制メソッドを使用してdomを参照することはできません。

代わりに、以下の例に示すように、React refシステムを使用してDomにアクセスして操作できます。

constructor(props){

    super(props);
    this.imageRef = React.createRef(); // create react ref
}

componentDidMount(){

    **console.log(this.imageRef)** // acessing the attributes of img tag when dom loads
}


render = (props) => {

const {urls,description} = this.props.image;
    return (

            <img
             **ref = {this.imageRef} // assign the ref of img tag here**
             src = {urls.regular} 
             alt = {description}
             />

        );

}

}


1
本当じゃない。img要素にIDを追加し、document.getElementByIdを使用してそれを取得できます。ほとんどの場合、IDは正常に機能します。問題が発生する可能性があります/コードのデバッグが難しくなりますが、react / jsxを使用するとネイティブのDomメソッドを使用できないようになります
adam tropp
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.