Context是局部的全局变量,使用Context避免通过中间元素传递props

    1. import "./styles.css";
    2. import React from 'react'
    3. // 创建一个context
    4. const ThemeContext = React.createContext('light');
    5. function F1(){
    6. return (
    7. <div>1
    8. <F2/>
    9. </div>
    10. )
    11. }
    12. function F2(){
    13. return (
    14. <div>2
    15. <F3/>
    16. </div>
    17. )
    18. }
    19. function F3(){
    20. return (
    21. <div>3
    22. {/* 用Consumer包住组件,函数形式传值 */}
    23. <ThemeContext.Consumer>
    24. {(n)=><F4 n={n}/>}
    25. </ThemeContext.Consumer>
    26. </div>
    27. )
    28. }
    29. function F4(props){
    30. return (
    31. <div>4, {props.n}</div>
    32. )
    33. }
    34. export default function App() {
    35. return (
    36. <div className="App">
    37. {/* 用Provider包住组件,并传递value */}
    38. <ThemeContext.Provider value='100'>
    39. <F1/>
    40. </ThemeContext.Provider>
    41. </div>
    42. );
    43. }

    consumer通过props.children调用传递的函数

    1. function Consumer(props){
    2. let x=100
    3. props.children(x)
    4. return (
    5. <div>hello</div>
    6. )
    7. }
    8. export default function App() {
    9. return (
    10. <Consumer>
    11. {(n)=>{console.log('我被调用了', 100)}}
    12. </Consumer>
    13. );
    14. }

    实践:点击按钮更换CSS样式
    (在codesandbox中编辑App.js文件)

    1. import "./styles.css";
    2. import React from "react";
    3. const themeContext = new React.createContext();
    4. function Box(props) {
    5. return <div className={props.theme}>{props.children}</div>; /* props.children获得子组件 */
    6. }
    7. function Button() {
    8. return <button>点我</button>;
    9. }
    10. function Input() {
    11. return <input />;
    12. }
    13. export default class App extends React.Component {
    14. constructor() {
    15. super();
    16. this.state = {
    17. theme: "red"
    18. };
    19. }
    20. changeTheme() {
    21. if (this.state.theme === "red") {
    22. this.setState({ theme: "green" });
    23. } else {
    24. this.setState({ theme: "red" });
    25. }
    26. }
    27. render() {
    28. return (
    29. <div>
    30. <button onClick={this.changeTheme.bind(this)}>换肤</button>
    31. <themeContext.Provider value={this.state.theme}> {/* 将值传给value */}
    32. {/* 哪个组件要用value,就用Consumer包起来,通过箭头函数形式传参数 */}
    33. <themeContext.Consumer>
    34. {/* 注意=>右边没有花括号 */}
    35. {theme=><div>
    36. <Box theme={theme}><Button/></Box>
    37. <Box theme={theme}><Input/></Box>
    38. </div>}
    39. </themeContext.Consumer>
    40. </themeContext.Provider>
    41. </div>
    42. );
    43. }
    44. }