组件通信有三种情况:
    1. 父组件和子组件进行通信:不推荐; (父组件拿到子组件的实例,进行一些操作;)

    1. 子组件和父组件通信: 比较常用;
    2. 兄弟组件之间进行通信:比较少用到;父组件可以做为他们之间的纽带进行通信;

    代码示例1:

    子组件和父组件的通信(子组件影响父组件的数据)。

    1. import React, {Component} from 'react';
    2. import ReactDOM from 'react-dom';
    3. import './index.css';
    4. import * as serviceWorker from './serviceWorker';
    5. import PropTypes from 'prop-types'
    6. class Clock extends Component {
    7. render() {
    8. let {time, onWake, onSleep} = this.props;
    9. if (time === 9) {
    10. onWake();
    11. }
    12. else if (time === 21) {
    13. onSleep();
    14. }
    15. return (<div>Clock</div>);
    16. }
    17. }
    18. class App extends Component{
    19. render(){
    20. return (<div>
    21. <Clock
    22. time={12}
    23. onWake={() => {
    24. alert('Wake up!');
    25. }}
    26. onSleep={() => {
    27. alert('Sleep!');
    28. }}
    29. />
    30. </div>);
    31. }
    32. }
    33. ReactDOM.render(<App />, document.getElementById('root'));
    34. // If you want your app to work offline and load faster, you can change
    35. // unregister() to register() below. Note this comes with some pitfalls.
    36. // Learn more about service workers: https://bit.ly/CRA-PWA
    37. serviceWorker.unregister();

    示例代码2:

    兄弟组件之间的通信。

    1. import React, {Component} from 'react';
    2. import ReactDOM from 'react-dom';
    3. import './index.css';
    4. import * as serviceWorker from './serviceWorker';
    5. import PropTypes from 'prop-types'
    6. class Action extends Component {
    7. constructor(props){
    8. super(props);
    9. this.state = {
    10. value: ''
    11. };
    12. }
    13. render() {
    14. return (<div style={{'padding-left': '20px', 'padding-top': '20px'}}>
    15. <input type='input' value={this.state.value} onChange={(e) => {
    16. this.setState({value: e.target.value});
    17. }}/>
    18. <button onClick={this.add.bind(this)}>Add</button>
    19. </div>);
    20. }
    21. add(){
    22. if(this.state.value !== '') {
    23. this.props.onAdd(this.state.value);
    24. this.setState({
    25. value: ''
    26. });
    27. }
    28. }
    29. }
    30. class TaskList extends Component {
    31. render() {
    32. let {data} = this.props;
    33. return (<div style={{'padding-left': 20 + 'px'}}>{data.map((item) => {
    34. return <div key={item.id}>{item.name}</div>;
    35. })}</div>);
    36. }
    37. }
    38. class App extends Component{
    39. constructor(props){
    40. super(props);
    41. this.state = {
    42. list: [
    43. {
    44. id: 1, name:'a'
    45. },
    46. {
    47. id: 2, name:'b'
    48. },
    49. {
    50. id: 3, name:'c'
    51. },
    52. ]
    53. };
    54. }
    55. render(){
    56. return (<div>
    57. <Action onAdd={this.onAdd.bind(this)}/>
    58. <TaskList data={this.state.list}/>
    59. </div>);
    60. }
    61. onAdd(item){
    62. let {list} = this.state;
    63. list.push({
    64. id: item,
    65. name: item
    66. });
    67. this.setState({
    68. list: list
    69. });
    70. }
    71. }
    72. ReactDOM.render(<App />, document.getElementById('root'));
    73. // If you want your app to work offline and load faster, you can change
    74. // unregister() to register() below. Note this comes with some pitfalls.
    75. // Learn more about service workers: https://bit.ly/CRA-PWA
    76. serviceWorker.unregister();

    组件通信示例3:
    父组件向子组件通信。
    注意 paddingLeft 的写法。 通过 ,就可以通过父组件.ref.list去获取子组件的实例。
    在console里调用 app.ref.list.clear() 去清除数据。

    1. import React, {Component} from 'react';
    2. import ReactDOM from 'react-dom';
    3. import './index.css';
    4. import * as serviceWorker from './serviceWorker';
    5. import PropTypes from 'prop-types'
    6. class List extends Component {
    7. constructor(props){
    8. super(props);
    9. this.state = {
    10. list: [
    11. {
    12. id: 1, name:'a'
    13. },
    14. {
    15. id: 2, name:'b'
    16. },
    17. {
    18. id: 3, name:'c'
    19. },
    20. ]
    21. };
    22. }
    23. render() {
    24. return (<div style={{'paddingLeft': 20 + 'px'}}>{this.state.list.map((item) => {
    25. return <div key={item.id}>{item.name}</div>;
    26. })}</div>);
    27. }
    28. clear(){
    29. this.setState({
    30. list: []
    31. });
    32. }
    33. }
    34. class App extends Component{
    35. render(){
    36. return (<div>
    37. <List ref="list"/>
    38. </div>);
    39. }
    40. componentDidMount(){
    41. window.app = this;
    42. }
    43. }
    44. ReactDOM.render(<App />, document.getElementById('root'));
    45. // If you want your app to work offline and load faster, you can change
    46. // unregister() to register() below. Note this comes with some pitfalls.
    47. // Learn more about service workers: https://bit.ly/CRA-PWA
    48. serviceWorker.unregister();

    观察者模式:

    1. import React, {Component} from 'react';
    2. import ReactDOM from 'react-dom';
    3. import './index.css';
    4. import * as serviceWorker from './serviceWorker';
    5. class EventComponent extends Component {
    6. cb = {};
    7. on(name, callback){
    8. this.cb[name] = callback;
    9. }
    10. off(name){
    11. delete this.cb[name];
    12. }
    13. trigger(name, args){
    14. this.cb[name](args);
    15. }
    16. }
    17. class Action extends EventComponent {
    18. constructor(props){
    19. super(props);
    20. this.state = {
    21. value: ''
    22. };
    23. }
    24. render() {
    25. return (<div style={{'paddingLeft': 20 + 'px'}}>
    26. <input type="input" value={this.state.value} onChange={(e) => {
    27. console.log(e);
    28. this.setState({value: e.target.value});
    29. }} />
    30. <button onClick={ (e) => {
    31. this.trigger('add', this.state.value);
    32. }}>Add</button>
    33. </div>);
    34. }
    35. }
    36. class List extends EventComponent {
    37. constructor(props){
    38. super(props);
    39. this.state = {
    40. list: [
    41. {
    42. id: 1, name:'a'
    43. },
    44. {
    45. id: 2, name:'b'
    46. },
    47. {
    48. id: 3, name:'c'
    49. },
    50. ]
    51. };
    52. }
    53. render() {
    54. return (<div style={{'paddingLeft': 20 + 'px'}}>{this.state.list.map((item) => {
    55. return <div key={item.id}>{item.name}</div>;
    56. })}</div>);
    57. }
    58. clear(){
    59. this.setState({
    60. list: []
    61. });
    62. }
    63. add(item){
    64. if(item !== '') {
    65. let {list} = this.state;
    66. list.push({
    67. id: item,
    68. name: item
    69. });
    70. this.setState({
    71. list: list
    72. });
    73. }
    74. }
    75. }
    76. class App extends EventComponent{
    77. render(){
    78. return (<div>
    79. <Action ref="action"/>
    80. <List ref="list"/>
    81. </div>);
    82. }
    83. componentDidMount(){
    84. let actionInstance = this.refs.action;
    85. let listInstance = this.refs.list;
    86. actionInstance.on('add', (item)=>{
    87. listInstance.add(item);
    88. });
    89. }
    90. }
    91. ReactDOM.render(<App />, document.getElementById('root'));
    92. // If you want your app to work offline and load faster, you can change
    93. // unregister() to register() below. Note this comes with some pitfalls.
    94. // Learn more about service workers: https://bit.ly/CRA-PWA
    95. serviceWorker.unregister();

    image.png
    image.png
    image.png