Подтвердить что ты не робот

Вызов метода компонента React извне

Я хочу вызвать метод, предоставляемый компонентом React, из экземпляра элемента React.

Например, в этом jsfiddle. Я хочу вызвать метод alertMessage из ссылки HelloElement.

Есть ли способ достичь этого без необходимости писать дополнительные обертки?

Изменить (скопированный код из JSFiddle)

<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')
);
4b9b3361

Ответ 1

Есть два способа получить доступ к внутренней функции. Один, уровень экземпляра, как вы хотите, другой, статический уровень.

Пример

Вам необходимо вызвать функцию по возвращении из React.render. Увидеть ниже.

статический

Посмотрите на ReactJS Statics. Обратите внимание, однако, что статическая функция не может получить доступ к данным уровня экземпляра, поэтому 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().

Ответ 2

Вы можете сделать как

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

Ответ 3

Я сделал что-то вроде этого:

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');
    }

}

Я не тестировал этот точный код, но это похоже на то, что я сделал в моем проекте, и оно работает прекрасно :). Конечно, это плохой пример, вы должны просто использовать для этого реквизиты, но в моем случае подкомпонент выполнил вызов API, который я хотел оставить внутри этого компонента. В таком случае это хорошее решение.

Ответ 4

При методе render который потенциально может исключать возвращаемое значение, рекомендуемый подход заключается в добавлении ссылки обратного вызова к корневому элементу. Как это:

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

к которому мы можем затем обратиться с помощью window.helloComponent, и любой из его методов может быть доступен с помощью window.helloComponent.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>

Ответ 5

Если вы используете ES6, просто используйте ключевое слово static для вашего метода из вашего примера: static alertMessage: function() { ...
},

Надежда может помочь кому угодно:)

Ответ 6

Вы можете просто добавить обработчик onClick в div с помощью функции (onClick является собственной реализацией onClick), и вы можете получить доступ к свойству в { } фигурных скобках, и появится ваше предупреждающее сообщение.

Если вы хотите определить статические методы, которые можно вызвать в классе компонентов, вы должны использовать статику. Хотя:

"Методы, определенные в этом блоке, являются статическими, что означает, что вы можете запускать их до создания любых экземпляров компонентов, а методы не имеют доступа к реквизитам или состоянию ваших компонентов. Если вы хотите проверить значение реквизита в статическом методе, вызывающий передается в реквизитах в качестве аргумента статического метода". (источник)

Пример кода:

    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);

Надеюсь, это поможет вам немного, потому что я не знаю, правильно ли я понял ваш вопрос, так что исправьте меня, если я его неправильно интерпретирую:)

Ответ 7

Похоже, статика устарела, а другие методы отображения некоторых функций с render кажутся запутанными. Между тем, этот ответ об ответе на отладку, в то время как выглядящий hack-y, сделал эту работу для меня.

Ответ 8

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

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

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

Вы можете вызвать этот метод из окна, используя window.alertMessage().

Ответ 9

Метод 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>

Ответ 10

У меня есть два ответа на этот вопрос:

1- используйте вашу функцию в качестве статического метода:

    statics: {
    alertMessage: function () {
        console.log('Method One');
    }
},

Но у этого метода есть большая проблема, потому что в статических методах у вас нет доступа к this и в случае, если вы хотите использовать this, этот метод не работает, поэтому в таких случаях используйте метод 2.

2- Первый в вашем class:

constructor(props){
    super(props);
    window.alertMessage = this.alertMessage.bind(this);
}

alertMessage () {
    console.log('Method Two');
}

тогда в каждом компоненте вы можете использовать команду ниже: