Я хочу вызвать метод, предоставляемый компонентом 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')
);
Ответы:
Есть два способа получить доступ к внутренней функции. Один, уровень экземпляра, как вы хотите, другой, статический уровень.
Пример
Вам нужно вызвать функцию при возврате из
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()
.источник
ref
которое представляет собой функцию, вызываемую с экземпляром в качестве параметра. Это также позволяет вам получить доступ к объектам, которые не находятся на верхнем уровне, например, при рендеринге<MuiThemeProvider><Hello ref={setHelloRef} /></MuiThemeProvider>
вы получаете правильную ссылку, переданную вашейsetHelloRef
функции, а не ссылкуMuiThemeProvider
.Вы можете сделать как
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();
источник
Я сделал что-то вроде этого:
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, который я хотел сохранить внутри этого компонента. В таком случае это хорошее решение.
источник
this.cowCallbacks.say('moo')
this
к обратному вызову (который будет экземпляром Cow) вместоcallbacks
.Поскольку
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>
источник
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()?
и он не привязывает компонент к окнуclass AppProvider extends Component { constructor() { super(); window.alertMessage = this.alertMessage.bind(this); } alertMessage() { console.log('Hello World'); } }
Вы можете вызвать этот метод из окна, используя
window.alertMessage()
.источник
Если вы работаете в ES6, просто используйте ключевое слово static в вашем методе из вашего примера:
static alertMessage: function() { ...
},
Надежда может помочь кому угодно :)
источник
С участием
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> </> ) }
Удачи...
источник
Вы можете просто добавить
onClick
обработчик к div с функцией (onClick
это собственная реализация ReactonClick
), и вы можете получить доступ к свойству в{ }
фигурных скобках, и появится ваше предупреждающее сообщение.Если вы хотите определить статические методы, которые могут быть вызваны в классе компонента, вам следует использовать статику. Несмотря на то что:
"Методы, определенные в этом блоке, являются статическими, что означает, что вы можете запускать их до того, как будут созданы какие-либо экземпляры компонентов, а методы не имеют доступа к свойствам или состоянию ваших компонентов. Если вы хотите проверить значение свойств в статическом метод, пусть вызывающий передает реквизиты в качестве аргумента статического метода ". ( источник )
Пример кода:
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);
Надеюсь, это вам немного поможет, потому что я не знаю, правильно ли я понял ваш вопрос, поэтому поправьте меня, если я неправильно его истолковал :)
источник
Похоже, что статика устарела, а другие методы раскрытия некоторых функций
render
кажутся запутанными. Между тем, этот ответ Stack Overflow об отладке React , хотя и казался хакерским, помог мне.источник
способ 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>
источник
Я использую этот вспомогательный метод для визуализации компонентов и возврата экземпляра компонента. В этом экземпляре можно вызывать методы.
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); }); }
источник