组件通信有三种情况:
1. 父组件和子组件进行通信:不推荐; (父组件拿到子组件的实例,进行一些操作;)
- 子组件和父组件通信: 比较常用;
- 兄弟组件之间进行通信:比较少用到;父组件可以做为他们之间的纽带进行通信;
代码示例1:
子组件和父组件的通信(子组件影响父组件的数据)。
import React, {Component} from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import * as serviceWorker from './serviceWorker';
import PropTypes from 'prop-types'
class Clock extends Component {
render() {
let {time, onWake, onSleep} = this.props;
if (time === 9) {
onWake();
}
else if (time === 21) {
onSleep();
}
return (<div>Clock</div>);
}
}
class App extends Component{
render(){
return (<div>
<Clock
time={12}
onWake={() => {
alert('Wake up!');
}}
onSleep={() => {
alert('Sleep!');
}}
/>
</div>);
}
}
ReactDOM.render(<App />, document.getElementById('root'));
// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();
示例代码2:
兄弟组件之间的通信。
import React, {Component} from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import * as serviceWorker from './serviceWorker';
import PropTypes from 'prop-types'
class Action extends Component {
constructor(props){
super(props);
this.state = {
value: ''
};
}
render() {
return (<div style={{'padding-left': '20px', 'padding-top': '20px'}}>
<input type='input' value={this.state.value} onChange={(e) => {
this.setState({value: e.target.value});
}}/>
<button onClick={this.add.bind(this)}>Add</button>
</div>);
}
add(){
if(this.state.value !== '') {
this.props.onAdd(this.state.value);
this.setState({
value: ''
});
}
}
}
class TaskList extends Component {
render() {
let {data} = this.props;
return (<div style={{'padding-left': 20 + 'px'}}>{data.map((item) => {
return <div key={item.id}>{item.name}</div>;
})}</div>);
}
}
class App extends Component{
constructor(props){
super(props);
this.state = {
list: [
{
id: 1, name:'a'
},
{
id: 2, name:'b'
},
{
id: 3, name:'c'
},
]
};
}
render(){
return (<div>
<Action onAdd={this.onAdd.bind(this)}/>
<TaskList data={this.state.list}/>
</div>);
}
onAdd(item){
let {list} = this.state;
list.push({
id: item,
name: item
});
this.setState({
list: list
});
}
}
ReactDOM.render(<App />, document.getElementById('root'));
// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();
组件通信示例3:
父组件向子组件通信。
注意 paddingLeft 的写法。 通过 ,就可以通过父组件.ref.list去获取子组件的实例。
在console里调用 app.ref.list.clear() 去清除数据。
import React, {Component} from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import * as serviceWorker from './serviceWorker';
import PropTypes from 'prop-types'
class List extends Component {
constructor(props){
super(props);
this.state = {
list: [
{
id: 1, name:'a'
},
{
id: 2, name:'b'
},
{
id: 3, name:'c'
},
]
};
}
render() {
return (<div style={{'paddingLeft': 20 + 'px'}}>{this.state.list.map((item) => {
return <div key={item.id}>{item.name}</div>;
})}</div>);
}
clear(){
this.setState({
list: []
});
}
}
class App extends Component{
render(){
return (<div>
<List ref="list"/>
</div>);
}
componentDidMount(){
window.app = this;
}
}
ReactDOM.render(<App />, document.getElementById('root'));
// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();
观察者模式:
import React, {Component} from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import * as serviceWorker from './serviceWorker';
class EventComponent extends Component {
cb = {};
on(name, callback){
this.cb[name] = callback;
}
off(name){
delete this.cb[name];
}
trigger(name, args){
this.cb[name](args);
}
}
class Action extends EventComponent {
constructor(props){
super(props);
this.state = {
value: ''
};
}
render() {
return (<div style={{'paddingLeft': 20 + 'px'}}>
<input type="input" value={this.state.value} onChange={(e) => {
console.log(e);
this.setState({value: e.target.value});
}} />
<button onClick={ (e) => {
this.trigger('add', this.state.value);
}}>Add</button>
</div>);
}
}
class List extends EventComponent {
constructor(props){
super(props);
this.state = {
list: [
{
id: 1, name:'a'
},
{
id: 2, name:'b'
},
{
id: 3, name:'c'
},
]
};
}
render() {
return (<div style={{'paddingLeft': 20 + 'px'}}>{this.state.list.map((item) => {
return <div key={item.id}>{item.name}</div>;
})}</div>);
}
clear(){
this.setState({
list: []
});
}
add(item){
if(item !== '') {
let {list} = this.state;
list.push({
id: item,
name: item
});
this.setState({
list: list
});
}
}
}
class App extends EventComponent{
render(){
return (<div>
<Action ref="action"/>
<List ref="list"/>
</div>);
}
componentDidMount(){
let actionInstance = this.refs.action;
let listInstance = this.refs.list;
actionInstance.on('add', (item)=>{
listInstance.add(item);
});
}
}
ReactDOM.render(<App />, document.getElementById('root'));
// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();