বাইরে থেকে একটি প্রতিক্রিয়া উপাদান পদ্ধতি কল করুন


95

আমি প্রতিক্রিয়া উপাদানটির দ্বারা প্রতিক্রিয়া উপাদান দ্বারা প্রকাশিত কোনও পদ্ধতিতে কল করতে চাই।

উদাহরণস্বরূপ, এই jsfiddle মধ্যে । আমি alertMessageপদ্ধতিটি HelloElementরেফারেন্স থেকে কল করতে চাই ।

অতিরিক্ত মোড়ক না লিখে এ অর্জনের কি উপায় আছে?

সম্পাদনা করুন (জেএসফিডাল থেকে অনুলিপি কোড)

<div id="container"></div>
<button onclick="onButtonClick()">Click me!</button>
var onButtonClick = function () {

    //call alertMessage method from the reference of a React Element! Something like HelloElement.alertMessage()
    console.log("clicked!");
}

var Hello = React.createClass({displayName: 'Hello',

    alertMessage: function() {
        alert(this.props.name);                             
    },

    render: function() {
        return React.createElement("div", null, "Hello ", this.props.name);
    }
});

var HelloElement = React.createElement(Hello, {name: "World"});

React.render(
    HelloElement,
    document.getElementById('container')
);

4
আদর্শ নয়, তবে জেএসফিডাল এতটাই সাধারণ যে এটি কোনও ডাউন-ভোটের নিশ্চয়তা দেয় না।
জেফ ফেয়ারি

আমি ভাবছি আপনার ব্যবহারের ক্ষেত্রে কী এমন হতে পারে যা এই জাতীয় জিনিসটিকে পরোয়ানা দেয়। এটি আপনার অ্যাপ্লিকেশন ইমো ডিজাইন করার ভাল উপায় নয়। আপনার যদি কোনও কিছু পুনরায় আকারে লাগানোর প্রয়োজন হয় তবে দয়া করে তৃতীয় কোনও ফাইলে একটি পৃথক সাধারণ সহায়ক তৈরি করুন এবং এটি আপনার বোতামের পাশাপাশি আপনার প্রতিক্রিয়া উপাদানটির জন্য ব্যবহার করুন।
টিফ্ল্যাভোরড

উত্তর:


56

একটি অভ্যন্তরীণ ফাংশন অ্যাক্সেস করার দুটি উপায় আছে। একটি, উদাহরণ-স্তর, যেমন আপনি চান, অন্যটি, স্থির স্তর।

দৃষ্টান্ত

আপনি থেকে ফেরত উপর ফাংশন কল করতে প্রয়োজন React.render। নিচে দেখ.

স্থির

রিএ্যাকটিজেএস স্ট্যাটিক্সটি একবার দেখুন । দ্রষ্টব্য, তবে, কোনও স্থির ফাংশন উদাহরণ-স্তরের ডেটা অ্যাক্সেস করতে পারে না, তাই thisহবে undefined

var onButtonClick = function () {
    //call alertMessage method from the reference of a React Element! 
    HelloRendered.alertMessage();
    //call static alertMessage method from the reference of a React Class! 
    Hello.alertMessage();
    console.log("clicked!");
}

var Hello = React.createClass({
    displayName: 'Hello',
    statics: {
        alertMessage: function () {
            alert('static message');
        }
    },
    alertMessage: function () {
        alert(this.props.name);
    },

    render: function () {
        return React.createElement("div", null, "Hello ", this.props.name);
    }
});

var HelloElement = React.createElement(Hello, {
    name: "World"
});

var HelloRendered = React.render(HelloElement, document.getElementById('container'));

তাহলে কর HelloRendered.alertMessage()


13
নোট করুন যে রেন্ডারের রিটার্ন মানটি অবহিত হিসাবে বিবেচিত হবে এবং পারফরম্যান্স বর্ধনগুলি সক্ষম করতে ভবিষ্যতের সংস্করণগুলিতে অপসারণ করা হবে বলে আশা করা হচ্ছে। আপনার উপাদান উপাদান অবজেক্টের রেফারেন্স পাওয়ার সমর্থিত উপায় হ'ল একটি বৈশিষ্ট্য যুক্ত করা refযা একটি প্যারামিটার হিসাবে উদাহরণ হিসাবে ডাকা হয়। এটি আপনাকে শীর্ষ স্তরের নয় এমন বস্তুগুলিতে অ্যাক্সেস করার অনুমতিও দেয়, যেমন আপনি যদি রেন্ডারিং করে থাকেন তবে একের পরিবর্তে <MuiThemeProvider><Hello ref={setHelloRef} /></MuiThemeProvider>আপনার setHelloRefফাংশনে সঠিক রেফারেন্সটি পেয়ে যাবেন MuiThemeProvider
পেরিটা ব্রেটা

আনকাচড টাইপ এরির: _react2.default.render কোনও ফাংশন নয়
পার্থ পল

46

আপনি পছন্দ করতে পারেন

import React from 'react';

class Header extends React.Component{

    constructor(){
        super();
        window.helloComponent = this;
    }

    alertMessage(){
       console.log("Called from outside");
    }

    render(){

      return (
      <AppBar style={{background:'#000'}}>
        Hello
      </AppBar>
      )
    }
}

export default Header;

এখন এই উপাদানটির বাইরে থেকে আপনি নীচের মত কল করতে পারেন

window.helloComponent.alertMessage();

4
আসলে, সহজ এবং ক্রিয়ামূলক! এটি যেমন অনুমিত হয়। আমি কতটা সহজ তা দেখে আমি খুব মুগ্ধ; সত্যিই সম্পর্কে চিন্তা না। আপনার যদি আরও বেশি সংখ্যক উপাদান থাকা উচিত তবে সম্ভবত এই পদ্ধতির তেমন ভাল কাজ হবে না। ধন্যবাদ!
লিওনার্দো মাফেই

6
গ্লোবাল ভেরিয়েবল যুক্ত করা ভাল সমাধান নয়। গ্লোবাল ভেরিয়েবলগুলি এখানে কেন খারাপ More সে সম্পর্কে আরও: wiki.c2.com/?GlobalVariablesAreBad
সালভাতোর জাপালি

4
ডাউন ভোটের জন্য ধন্যবাদ !! হ্যাঁ গ্লোবাল ভেরিয়েবল ভাল না তবে এটি আপনার সমস্যা সমাধানের একটি উপায়।
কুশল জৈন

4
এটি হ'ল বাস্তববাদী এবং সহজ সমাধানটি আমার দরকার, ধন্যবাদ!
ফ্লোরেন্ট ডাস্ট্রেমাউ 12'19

4
এটি কাজ করেছে তবে একই পৃষ্ঠায় আপনার একাধিক একই উপাদান থাকলে এটি কাজ করবে না।
গৌরব

26

আমি এরকম কিছু করেছি:

class Cow extends React.Component {

    constructor (props) {
        super(props);
        this.state = {text: 'hello'};
    }

    componentDidMount () {
        if (this.props.onMounted) {
            this.props.onMounted({
                say: text => this.say(text)
            });
        }
    }

    render () {
        return (
            <pre>
                 ___________________
                < {this.state.text} >
                 -------------------
                        \   ^__^
                         \  (oo)\_______
                            (__)\       )\/\
                                ||----w |
                                ||     ||
            </pre>
        );
    }

    say (text) {
        this.setState({text: text});
    }

}

এবং তারপরে অন্য কোথাও:

class Pasture extends React.Component {

    render () {
        return (
            <div>
                <Cow onMounted={callbacks => this.cowMounted(callbacks)} />
                <button onClick={() => this.changeCow()} />
            </div>
        );
    }

    cowMounted (callbacks) {
        this.cowCallbacks = callbacks;
    }

    changeCow () {
        this.cowCallbacks.say('moo');
    }

}

আমি এই সঠিক কোডটি পরীক্ষা করি নি, তবে এটি আমার একটি প্রকল্পে আমি যা করেছি তার লাইনের সাথে রয়েছে এবং এটি দুর্দান্তভাবে কাজ করে :) :) অবশ্যই এটি একটি খারাপ উদাহরণ, আপনার কেবল প্রপস ব্যবহার করা উচিত, তবে আমার ক্ষেত্রে সাব-উপাদানটি একটি এপিআই কল করেছিল যা আমি সেই উপাদানটির ভিতরে রাখতে চেয়েছিলাম to সেক্ষেত্রে এটি একটি দুর্দান্ত সমাধান।


4
আমি মনে করি আপনি বোঝাতে চেয়েছিলেনthis.cowCallbacks.say('moo')
স্টিভেন

বিটিডাব্লু এর thisপরিবর্তে কলব্যাক (যা গরুর উদাহরণ হতে পারে) পাস করা সম্ভব callbacks
ওয়েবব্রোডার

@ ওয়েবব্রথ হ্যাঁ, তবে এটি আরও হ্যাকি হবে
গীতারিক

6

সঙ্গে renderপদ্ধতি সম্ভাব্য ফিরে মান বিনয়ী, প্রস্তাবিত পদ্ধতির মূল উপাদান করার জন্য একটি কলব্যাক সুত্র সংযুক্ত করতে এখন হয়। এটার মত:

ReactDOM.render( <Hello name="World" ref={(element) => {window.helloComponent = element}}/>, document.getElementById('container'));

যার পরে আমরা উইন্ডো.হেলো কম্পোনেন্ট ব্যবহার করে অ্যাক্সেস করতে পারি এবং এর যে কোনও পদ্ধতিতে উইন্ডো.হেলো কম্পোনেন্ট.METHOD দিয়ে অ্যাক্সেস করা যায়।

এখানে একটি সম্পূর্ণ উদাহরণ:

var onButtonClick = function() {
  window.helloComponent.alertMessage();
}

class Hello extends React.Component {
  alertMessage() {
    alert(this.props.name);
  }

  render() {
    return React.createElement("div", null, "Hello ", this.props.name);
  }
};

ReactDOM.render( <Hello name="World" ref={(element) => {window.helloComponent = element}}/>, document.getElementById('container'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="container"></div>
<button onclick="onButtonClick()">Click me!</button>


উইন্ডো অবজেক্টের পরিবর্তে স্থানীয় অবস্থায় রেফারেন্স দেওয়া ভাল ... ref={component => {this.setState({ helloComponent: component; })}} তারপরে, ক্লিক হ্যান্ডলারটিতে ... this.state.helloComponent.alertMessage();
বিল ড্যাগ

আমার পূর্ববর্তী মন্তব্যে আরও ... বা আরও ভাল, কেবলমাত্র উপাদানটির সতর্কতা পদ্ধতি পদ্ধতিটিকে রাজ্যে রাখুন।
বিল ড্যাগ

যখন আমি Warning: Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?এটির চেষ্টা করি এবং এটি উইন্ডোতে উপাদান আবদ্ধ হয় না
গেরিলা

4
class AppProvider extends Component {
  constructor() {
    super();

    window.alertMessage = this.alertMessage.bind(this);
  }

  alertMessage() {
    console.log('Hello World');
 }
}

আপনি উইন্ডো থেকে এই পদ্ধতিটি কল করে কল করতে পারেন window.alertMessage()


এটি কার্যকর হবে তবে বহুবিধ কারণে বিশ্বব্যাপী পরিবর্তনশীল যুক্ত করা ভাল সমাধান নয়। : আপনি কেন গ্লোবাল ভেরিয়েবল খারাপ এখানে আছেন উপর আরও তথ্য পেতে পারেন wiki.c2.com/?GlobalVariablesAreBad
সালভাতোরে Zappalà

3

আপনি যদি ES6 এ থাকেন তবে আপনার উদাহরণ থেকে আপনার পদ্ধতিতে "স্থিতিক" কীওয়ার্ডটি ব্যবহার করুন নিম্নলিখিতটি হবে: static alertMessage: function() { ...
},

আশা করি যে কেউ এখানে সাহায্য করতে পারে :)


আপনি কোনও স্থির ক্রিয়ায় প্রপস বা রাজ্যে পৌঁছাতে পারবেন না।
সর্দার Değirmenci

হ্যাঁ হ্যাঁ, তবে প্রশ্নটি সতর্কতা ম্যাসেজ () ফাংশনটি অ্যাক্সেস করতে চলেছে যাতে আপনি হ্যালোইলমেন্ট.এলার্টমেসেজ () ব্যবহার করতে পারেন।
darmis

সাধারণত প্রপস এবং রাষ্ট্র ব্যবহার না করে কোনও ফাংশন কল করার কোনও প্রভাব নেই। তবে আপনি যেমন
ফাংশনটিতে

3

সঙ্গে React hook - useRef



const MyComponent = ({myRef}) => {
  const handleClick = () => alert('hello world')
  myRef.current.handleClick = handleClick
  return (<button onClick={handleClick}>Original Button</button>)
}

MyComponent.defaultProps = {
  myRef: {current: {}}
}

const MyParentComponent = () => {
  const myRef = React.useRef({})
  return (
    <>
      <MyComponent 
        myRef={myRef}
      />
      <button onClick={myRef.current.handleClick}>
        Additional Button
      </button>
    </>
  )
}

শুভকামনা ...


2

আপনি কেবলমাত্র onClickফাংশনটির সাথে ডিভিতে একটি হ্যান্ডলার যুক্ত করতে পারেন ( onClickএটি তার নিজস্ব বাস্তবায়নের onClick) এবং আপনি এর মধ্যে সম্পত্তি অ্যাক্সেস করতে পারেন{ } কোঁকড়া ধনুর্বন্ধনী , এবং আপনার সতর্কতা বার্তা প্রদর্শিত হবে।

যদি আপনি স্থিতিশীল পদ্ধতিগুলি সংজ্ঞায়িত করতে চান যা উপাদান শ্রেণিতে কল করা যায় - আপনার স্ট্যাটিক্স ব্যবহার করা উচিত। যদিও:

"এই ব্লকের মধ্যে সংজ্ঞায়িত পদ্ধতিগুলি স্থিতিশীল, এর অর্থ যে কোনও উপাদান উপাদান তৈরি হওয়ার আগে আপনি এগুলি চালাতে পারবেন এবং পদ্ধতিগুলি আপনার উপাদানগুলির প্রপস বা অবস্থানে অ্যাক্সেস পাবে না If আপনি যদি একটি স্ট্যাটিকের প্রপসের মান পরীক্ষা করতে চান পদ্ধতি, স্থির পদ্ধতির যুক্তি হিসাবে কলগুলিকে প্রপসগুলিতে পাস করুন। ( উত্স )

কিছু উদাহরণ কোড:

    const Hello = React.createClass({

        /*
            The statics object allows you to define static methods that can be called on the component class. For example:
        */
        statics: {
            customMethod: function(foo) {
              return foo === 'bar';
            }
        },


        alertMessage: function() {
            alert(this.props.name);                             
        },

        render: function () {
            return (
                <div onClick={this.alertMessage}>
                Hello {this.props.name}
                </div>
            );
        }
    });

    React.render(<Hello name={'aworld'} />, document.body);

আশা করি এটি আপনাকে কিছুটা সহায়তা করবে, কারণ আমি জানি না যে আমি আপনার প্রশ্নটি সঠিকভাবে বুঝতে পেরেছি কিনা, তাই যদি আমি এটির ভুল ব্যাখ্যা করি তবে আমাকে সংশোধন করুন :)


2

এটি প্রদর্শিত হয় যে স্ট্যাটিকগুলি হ্রাস করা হয়, এবং কিছু ফাংশন প্রকাশের অন্যান্য পদ্ধতিগুলি renderগুলিয়ে যায় বলে মনে হয়। ইতিমধ্যে, ডিবাগিংয়ের বিষয়ে এই স্ট্যাক ওভারফ্লো উত্তরটি হ্যাক- ওয়াইয়ের সময় মনে হচ্ছে, আমার পক্ষে কাজটি করেছে।


2

পদ্ধতি 1 using ChildRef :

public childRef: any = React.createRef<Hello>();

public onButtonClick= () => {
    console.log(this.childRef.current); // this will have your child reference
}

<Hello ref = { this.childRef }/>
<button onclick="onButtonClick()">Click me!</button>

পদ্ধতি 2: using window register

public onButtonClick= () => {
    console.log(window.yourRef); // this will have your child reference
}

<Hello ref = { (ref) => {window.yourRef = ref} }/>`
<button onclick="onButtonClick()">Click me!</button>

সন্তানের উপাদানগুলির পদ্ধতিগুলি অ্যাক্সেস করার 1 পদ্ধতিটি একটি খুব সহজ এবং পরিষ্কার উপায়। ধন্যবাদ!
গাবদারা

1

আমি উপাদানগুলি রেন্ডার করতে এবং কোনও উপাদান উদাহরণ ফিরিয়ে দিতে এই সহায়ক পদ্ধতিটি ব্যবহার করি। পদ্ধতিগুলি উদাহরণ হিসাবে বলা যেতে পারে।

static async renderComponentAt(componentClass, props, parentElementId){
         let componentId = props.id;
        if(!componentId){
            throw Error('Component has no id property. Please include id:"...xyz..." to component properties.');
        }

        let parentElement = document.getElementById(parentElementId);

        return await new Promise((resolve, reject) => {
            props.ref = (component)=>{
                resolve(component);
            };
            let element = React.createElement(componentClass, props, null);
            ReactDOM.render(element, parentElement);
        });
    }
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.