组件通信有三种情况:
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><Clocktime={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-PWAserviceWorker.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-PWAserviceWorker.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-PWAserviceWorker.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-PWAserviceWorker.unregister();



