ReactJS में "बाहर" से घटक विधियों का उपयोग कैसे करें?


182

मैं ReactJS में "बाहर" से घटक विधियों का उपयोग क्यों नहीं कर सकता हूं? यह क्यों संभव नहीं है और क्या इसे हल करने का कोई तरीका है?

कोड पर विचार करें:

var Parent = React.createClass({
    render: function() {
        var child = <Child />;
        return (
            <div>
                {child.someMethod()} // expect "bar", got a "not a function" error.
            </div>
        );
    }
});

var Child = React.createClass({
    render: function() {
        return (
            <div>
                foo
            </div>
        );
    },
    someMethod: function() {
        return 'bar';
    }
});

React.renderComponent(<Parent />, document.body);

शायद आपको जरूरत हो Pubsub?
स्लाइड शो 2

जवाबों:


203

प्रतिक्रिया आपको refविशेषता के माध्यम से जो करने की कोशिश कर रही है उसके लिए एक इंटरफ़ेस प्रदान करता है । एक घटक को असाइन करें ref, और इसकी currentविशेषता आपका कस्टम घटक होगा:

class Parent extends React.Class {
    constructor(props) {
        this._child = React.createRef();
    }

    componentDidMount() {
        console.log(this._child.current.someMethod()); // Prints 'bar'
    }

    render() {
        return (
            <div>
                <Child ref={this._child} />
            </div>
        );
    }
}

नोट : यह केवल तभी काम करेगा जब बाल घटक को एक वर्ग के रूप में घोषित किया गया हो, जैसा कि यहां पाया गया है: https://facebook.github.io/react/docs/refs-and-the-dom.html#adding-a- रेफरी करने वाली एक श्रेणी के घटक

अपडेट 2019-04-01: एक वर्ग और createRefप्रति नवीनतम रिएक्ट डॉक्स का उपयोग करने के लिए परिवर्तित उदाहरण ।

अपडेट 2016/09/19: बदला गया उदाहरण से मार्गदर्शन प्रति रेफरी कॉलबैक उपयोग करने के लिए स्ट्रिंग विशेषता डॉक्स।ref


तो, दो बाल घटकों के बीच संवाद करने का एकमात्र तरीका रेफरी होने और आम माता-पिता पर एक प्रॉक्सी पद्धति से गुजरने के साथ होगा?
elQueFaltaba

15
प्रतिक्रिया डेटा-संचालित घटकों को प्रोत्साहित करती है। एक बच्चे को एक कॉलबैक बताएं जो उसके पूर्वज में डेटा बदलता है, और जब वह डेटा बदलता है तो दूसरे बच्चे को नया propsऔर उचित रूप से फिर से प्रस्तुत करना होगा।
रॉस एलेन

@RossAllen, हाहा हाँ, आपको उस मामले में अर्धविराम भी हटाना होगा।
हुसैनक सिप

@ हसिएनक मैं एक ब्लॉक का उपयोग करना पसंद करता हूं यदि फ़ंक्शन का कोई वापसी मूल्य नहीं होना चाहिए, तो अगले डेवलपर के लिए इरादा स्पष्ट है जो कोड पढ़ता है। यह बदलना कि {(child) => this._child = child}एक ऐसा फंक्शन बनाया जाएगा जो हमेशा लौट आए true, लेकिन उस मूल्य का उपयोग रिएक्ट के refगुण द्वारा नहीं किया जाता है ।
रॉस एलन

39

यदि आप प्रतिक्रिया के बाहर से घटकों पर फ़ंक्शन कॉल करना चाहते हैं, तो आप उन्हें रेंडरकंपोनेंट के वापसी मूल्य पर कॉल कर सकते हैं:

var Child = React.createClass({…});
var myChild = React.renderComponent(Child);
myChild.someMethod();

React.renderComponent के रिटर्न मान को संग्रहीत करके प्रतिक्रिया के बाहर एक रिएक्टर घटक उदाहरण के लिए एक हैंडल प्राप्त करने का एकमात्र तरीका है। स्रोत


1
वास्तव में यह प्रतिक्रिया 16 के लिए काम करता है। ReactDOM रेंडर विधि घटक के संदर्भ (या स्टेटलेस घटकों के लिए शून्य) लौटाता है।
व्लाद पोवलि

37

वैकल्पिक रूप से, यदि चाइल्ड पर विधि वास्तव में स्थिर है (वर्तमान प्रॉप्स, राज्य का उत्पाद नहीं है) तो आप इसे परिभाषित कर सकते हैं staticsऔर फिर इसे तब तक एक्सेस कर सकते हैं जब आप स्टैटिक क्लास विधि करेंगे। उदाहरण के लिए:

var Child = React.createClass({
  statics: {
    someMethod: function() {
      return 'bar';
    }
  },
  // ...
});

console.log(Child.someMethod()) // bar

1
इसके लिए स्रोत यहाँ है
tirdadc

7

प्रतिक्रिया के रूप में 16.3 React.createRefका उपयोग किया जा सकता है, (उपयोग ref.currentकरने के लिए उपयोग)

var ref = React.createRef()

var parent = <div><Child ref={ref} /> <button onClick={e=>console.log(ref.current)}</div>

React.renderComponent(parent, document.body)


1

आप इसे इस तरह भी कर सकते हैं, सुनिश्चित नहीं है कि यह एक अच्छी योजना है: डी

class Parent extends Component {
  handleClick() {
    if (this._getAlert !== null) {
      this._getAlert()
    }
  }

  render() {
    return (
      <div>
        <Child>
        {(getAlert, childScope) => (
          <span> {!this._getAlert ? this._getAlert = getAlert.bind(childScope) : null}</span>
        )}
        </Child>
        <button onClick={() => this.handleClick()}> Click me</button>
      </div>
      );
    }
  }

class Child extends Component {
  constructor() {
    super();
    this.state = { count: 0 }
  }

  getAlert() {
    alert(`Child function called state: ${this.state.count}`);
    this.setState({ count: this.state.count + 1 });
  }

  render() {
    return this.props.children(this.getAlert, this)
  }
}

1

जैसा कि कुछ टिप्पणियों में उल्लेख किया गया है, ReactDOM.renderअब घटक उदाहरण नहीं देता है। आप refकॉलबैक पास कर सकते हैं जब उदाहरण प्राप्त करने के लिए घटक की जड़ को प्रस्तुत किया जाए, जैसे:

// React code (jsx)
function MyWidget(el, refCb) {
    ReactDOM.render(<MyComponent ref={refCb} />, el);
}
export default MyWidget;

तथा:

// vanilla javascript code
var global_widget_instance;

MyApp.MyWidget(document.getElementById('my_container'), function(widget) {
    global_widget_instance = widget;
});

global_widget_instance.myCoolMethod();

-1

एक और तरीका इतना आसान है:

बाहर कार्य:

function funx(functionEvents, params) {
  console.log("events of funx function: ", functionEvents);
  console.log("this of component: ", this);
  console.log("params: ", params);
  thisFunction.persist();
}

इसे बांधें:

constructor(props) {
   super(props);
    this.state = {};
    this.funxBinded = funx.bind(this);
  }
}

कृपया यहां पूरा ट्यूटोरियल देखें: बाहर से रिएक्ट कंपोनेंट के "इस" का उपयोग कैसे करें?

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.