https://www.jianshu.com/p/fb915d9c99c4

父组件向子组件传值

父组件通过向子组件传递props, 子组件得到props后进行相应的处理。

  1. /* 父组件 App.js */
  2. import React,{ Component } from "react";
  3. import Sub from "./SubComponent.js";
  4. import "./App.css";
  5. export default class App extends Component{
  6. render(){
  7. return(
  8. <div>
  9. <Sub title = "今年过节不收礼" />
  10. </div>
  11. )
  12. }
  13. }
  14. /* 子组件 SubComponent.js */
  15. import React from "react";
  16. const Sub = (props) => {
  17. return(
  18. <h1>
  19. { props.title }
  20. </h1>
  21. )
  22. }
  23. export default Sub;

子组件向父组件传值

父组件将一个函数作为 props 传递给子组件,子组件调用该回调函数,便可以向父组件通信。

  1. /* 父组件 App.js */
  2. import React,{ Component } from "react";
  3. import Sub from "./SubComponent.js";
  4. import "./App.css";
  5. export default class App extends Component{
  6. callback(msg){
  7. console.log(msg);
  8. }
  9. render(){
  10. return(
  11. <div>
  12. <Sub callback = { this.callback.bind(this) } />
  13. </div>
  14. )
  15. }
  16. }
  17. /* 子组件 SubComponent.js */
  18. import React from "react";
  19. const Sub = (props) => {
  20. const cb = (msg) => {
  21. return () => {
  22. props.callback(msg)
  23. }
  24. }
  25. return(
  26. <div>
  27. <button onClick = { cb("我们通信把") }>点击我</button>
  28. </div>
  29. )
  30. }
  31. export default Sub;

跨级组件之间通信

所谓跨级组件通信,就是父组件向子组件的子组件通信,向更深层的子组件通信。跨级组件通信可以采用下面两种方式:

  • 中间组件层层传递 props
  • 使用 context 对象

对于第一种方式,如果父组件结构较深,那么中间的每一层组件都要去传递 props,增加了复杂度,并且这些 props 并不是这些中间组件自己所需要的。不过这种方式也是可行的,当组件层次在三层以内可以采用这种方式,当组件嵌套过深时,采用这种方式就需要斟酌了。
使用 context 是另一种可行的方式,context 相当于一个全局变量,是一个大容器,我们可以把要通信的内容放在这个容器中,这样一来,不管嵌套有多深,都可以随意取用。
使用 context 也很简单,需要满足两个条件:

  • 上级组件要声明自己支持 context,并提供一个函数来返回相应的 context 对象
  • 子组件要声明自己需要使用 context

下面以代码说明,我们新建 3 个文件:父组件 App.js,子组件 Sub.js,子组件的子组件 SubSub.js。

  1. /* App.js */
  2. import React, { Component } from 'react';
  3. import PropTypes from "prop-types";
  4. import Sub from "./Sub";
  5. import "./App.css";
  6. export default class App extends Component{
  7. // 父组件声明自己支持 context
  8. static childContextTypes = {
  9. color:PropTypes.string,
  10. callback:PropTypes.func,
  11. }
  12. // 父组件提供一个函数,用来返回相应的 context 对象
  13. getChildContext(){
  14. return{
  15. color:"red",
  16. callback:this.callback.bind(this)
  17. }
  18. }
  19. callback(msg){
  20. console.log(msg)
  21. }
  22. render(){
  23. return(
  24. <div>
  25. <Sub></Sub>
  26. </div>
  27. );
  28. }
  29. }
  30. /* Sub.js */
  31. import React from "react";
  32. import SubSub from "./SubSub";
  33. const Sub = (props) =>{
  34. return(
  35. <div>
  36. <SubSub />
  37. </div>
  38. );
  39. }
  40. export default Sub;
  41. /* SubSub.js */
  42. import React,{ Component } from "react";
  43. import PropTypes from "prop-types";
  44. export default class SubSub extends Component{
  45. // 子组件声明自己需要使用 context
  46. static contextTypes = {
  47. color:PropTypes.string,
  48. callback:PropTypes.func,
  49. }
  50. render(){
  51. const style = { color:this.context.color }
  52. const cb = (msg) => {
  53. return () => {
  54. this.context.callback(msg);
  55. }
  56. }
  57. return(
  58. <div style = { style }>
  59. SUBSUB
  60. <button onClick = { cb("我胡汉三又回来了!") }>点击我</button>
  61. </div>
  62. );
  63. }
  64. }

非嵌套组件通信