React'taki bir DOM öğesine nasıl erişilir? React içindeki document.getElementById () 'nin dengesi nedir


205

Reakt.js'de belirli çubukları nasıl seçerim?

Bu benim kodum:

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 (...);
    }

Bu React bileşenini kullanmak istiyorum:

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 işlevini yürütmek ve seçili ilerleme çubuğum için işlemi gerçekleştirmek istiyorum. Ama elde ettiğim sonuç:

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

Reakt.js'de belirli Öğeyi nasıl seçerim?

Yanıtlar:


215

Bunu, ref

EDIT: v16.8.0 ile fonksiyonel bileşen reaksiyonunda useRef ile bir ref tanımlayabilirsiniz. İşlevsel bir bileşende ref belirttiğinizde, ref'yi DOM kullanım öğesine iletmek için üzerinde React.forwardRef kullanmanız gerektiğini unutmayın.useImperativeHandle fonksiyonel bileşen içerisinden belirli işlevleri ortaya çıkarmak için

Ör:

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} />
        </>
    )
}

DÜZENLE:

Gelen 16.3+ Tepki , kullanımı React.createRef()sizin ref oluşturmak için:

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

Öğeye erişmek için şunu kullanın:

const node = this.myRef.current;

React.createRef () kullanmak için DOC


DÜZENLE

Bununla birlikte, facebook dize ref'lerinin bazı sorunları olduğundan, eski olarak kabul edildiğinden ve gelecekteki sürümlerden birinde kaldırılacağı için buna karşı tavsiyede bulunur.

Dokümanlardan:

Eski API: Dize Referansları

Daha önce React ile çalıştıysanız, ref özniteliğinin "textInput" gibi bir dize olduğu ve DOM düğümüne this.refs.textInput olarak erişildiği daha eski bir API'ye aşina olabilirsiniz. Dize ref'lerinin bazı sorunları olduğundan, eski olarak kabul edildiğinden ve gelecekteki sürümlerden birinde kaldırılması muhtemel olduğundan buna karşı öneriyoruz. Şu anda ref'lere erişmek için this.refs.textInput kullanıyorsanız, bunun yerine geri arama modelini kullanmanızı öneririz.

React 16.2 ve öncesi için önerilen bir yol , geri arama modelini kullanmaktır:

<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 }}/>

Geri aramayı kullanmak için DOC


Aşağıdaki gibi dize kullanarak reaksiyon tanımlanmış referansların daha eski sürümleri bile

<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"/>

Öğeyi almak için sadece

var object = this.refs.Progress1;

Aşağıdaki thisgibi bir ok fonksiyon bloğunun içinde kullanmayı unutmayın :

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

ve bunun gibi...


5
Facebook bu yaklaşıma karşı tavsiyede bulunuyor. Buraya bakın facebook.github.io/react/docs/refs-and-the-dom.html
Dmitry

4
@ dmitrymar Gördüğüm gibi yukarıdaki sayfa v15.4.2 için yazılmıştır ve sanırım, cevabı yazdığımda bu daha önce yoktu. Her neyse, cevabı doğru yaklaşımla düzenledi
Shubham Khatri

2
@MattSidor, düzenleme için teşekkürler, bana biraz zaman kazandın :-)
Shubham Khatri

Um, soru "bu" üzerinden erişemezsem, ne ihtiyacım bileşen başka bir sınıfın bir örnek ise? (örn., başka bir çocuk ana bileşen içindeki bileşene tepki gösterir)
akshay kishore

@akshaykishore Ref, innerRef diyelim başka bir ad kullanarak aşağı geçmek ve istenen bileşene geçmek gerekir
Shubham

37

Öğeyi içeri almak reactiçin kullanmanız refve işlevin içindeReactDOM.findDOMNode yöntemi.

Ama daha fazlasını yapmaktan hoşlandığım şey, etkinliğin içinde ref demek

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

Bu, anlamanıza yardımcı olacak iyi bir bağlantıdır .


2
Bunu yapmanın doğru yolu budur. Bu, nesne / sınıftaki öğeye this.myTextInputerişmek için kullanabileceğiniz bir başvuru ekler .
Sam Parmenter

1
Bunu dinamik olarak oluşturulmuş öğeyle nasıl yapabilirim?
Sagar Kodte

Çağrı React.findDOMNodebana verirreact__WEBPACK_IMPORTED_MODULE_0___default.a.findDOMNode is not a function
James Poulose

@JamesPoulose katı modda çalışmadığınızdan emin olun, çünkü tepki React.findDOMNodekatı modda kullanmanıza izin vermez .
Limpuls

13

Değiştirebilirsiniz

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

ile

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


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

3
Bunu dinamik olarak oluşturulmuş öğeyle nasıl yapabilirim?
Sagar Kodte

1

React bir HTML oluşturmak için JSX kodunu kullandığından, document.querySelector veya getElementById gibi düzenleme yöntemlerini kullanarak dom'a başvuramayız.

Bunun yerine, aşağıdaki örnekte gösterildiği gibi Dom'a erişmek ve bunları değiştirmek için React ref sistemini kullanabiliriz:

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
Bu doğru değil. İmg öğesine bir kimlik ekleyebilir, document.getElementById kullanarak yakalayabilirsiniz ve çoğu durumda düzgün çalışır. Sorunlara neden olabilir / kodunuzun hata ayıklamasını zorlaştırabilir, ancak tepki / jsx bunu yapmayın, böylece yerel Dom yöntemlerini
KULLANMAYIN
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.