[英]react.js: call a function from another component
我來自vue.js,因此對於反應還是有些困惑。
我有一個Message組件,它顯示Flash消息:
import React, {Component} from "react";
export default class Message extends Component {
constructor(props) {
super(props);
this.state = {messages: []};
}
setMessage(type, body) {
this.setState({messages: this.state.messages.concat({type: type, body: body})})
setTimeout(() => {
this.removeMessage()
}, 10000);
}
removeMessage() {
let messages = this.state.messages;
messages.shift();
this.setState({messages: messages});
}
render() {
return (
<div className="uk-messages">
{
this.state.messages.map((message, index) => {
if (message.type === 'error') {
message.type = 'danger';
}
return (
<div className={'uk-alert-' + message.type} data-uk-alert key={index}>
<p>{message.body}</p>
</div>
)
})
}
</div>
)
}
}
我在索引組件中使用此組件:
import React, {Component} from 'react'
import ReactDOM from 'react-dom'
import {BrowserRouter as Router, Link, Route, Redirect} from 'react-router-dom'
import Auth from './helpers/auth'
import Message from './helpers/message'
class Index extends Component {
constructor(props) {
super(props);
this.state = {
authState: Auth.state,
};
Auth.initialize();
}
render() {
return (
<Router>
<div className="uk-flex uk-flex-column">
<nav className="uk-navbar-container" data-uk-navbar>
<div className="uk-navbar-left">
<a className="uk-navbar-item uk-logo" href="#"><img src={'images/logo.png'}/></a>
<ul className="uk-navbar-nav">
<li><Link to="/">Home</Link></li>
</ul>
</div>
<div className="uk-navbar-right">
<ul className="uk-navbar-nav">
<li>
<a href="#" className="uk-open" aria-expanded="true">
<span data-uk-icon="icon: user" />
</a>
</li>
</ul>
</div>
</nav>
<div className="uk-flex-grow-1">
<Route path="/" component={Welcome} />
</div>
<footer>
© 2018 stackoverflow.com
</footer>
<Message />
</div>
</Router>
);
}
}
if (document.getElementById('root')) {
ReactDOM.render(<Index/>, document.getElementById('root'));
}
好的,所以索引組件是我開始使用的組件。 我導入消息組件並進行渲染。 這樣可行。 在chrome react控制台中,我選擇Message標簽,並可以添加一些消息,
$ r.setMessage('success','問候我的老朋友!')
出現信息。 因此,現在如何在索引組件中使用setMessage方法? 在vue.js中,它是如此簡單(使用$ parent或$ children)...
訪問另一個組件的方法的最直接方法是傳遞refs ,但是您可能應該以其他方式來處理該問題。 一旦開始將組件與ref綁定在一起,就使它們的可重用性降低,使用起來也更加困難。
如果消息列表存儲在較高級別,並且作為道具傳遞到Message
組件中,那么您就不需要引用。
因此,我建議將messages
移動到Index
組件的狀態(甚至可能移動到商店),然后將messages
作為道具傳遞給<Message messages={this.state.messages} />
。
如果您還想從Message
組件中操作消息,則還可以傳遞所需的<Index>
回調。
下面是一個玩具示例,顯示了將狀態存儲在父組件中並將messages
和addMessage
作為props傳遞給<Message>
的一般思想。
const Message = ({ messages, addMessage }) => ( <div> {messages.map(({ text, id }) => <div key={id}>{text}</div>)} <button onClick={addMessage}>add</button> </div> ); class Index extends React.Component { constructor(props) { super(props); this.addMessage = this.addMessage.bind(this); } state = { messages: [], id: 0 }; addMessage() { this.setState({ messages: [...this.state.messages, { text: "new message", id: this.state.id }], id: this.state.id + 1 }); } render() { return <Message messages={this.state.messages} addMessage={this.addMessage} /> } } ReactDOM.render(<Index/>, document.getElementById("root"));
<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="root"></div>
您可以使用refs
獲得對元素的引用,例如
<Message refs={(ref) => this.messageElement = ref }/>
這樣,您就可以在分配之后從任何地方調用方法
this.messageElement.setMessage();
您可以將refs(引用)用作
<Message ref={(c) => this.messageComponent = c} />
並使Message
組件的功能與上下文綁定在一起,以便在其他組件(例如
Message
組件
constructor(props) {
super(props);
this.state = {messages: []};
this.setMessage = this.setMessage.bind(this);
}
Index
組件中的用法
this.messageComponent.setMessage('type','body');
在這里閱讀更多參考
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.