Вызов метода компонента 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')
);
Ответы
Ответ 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');
}
тогда в каждом компоненте вы можете использовать команду ниже: