美文网首页程序员
9天深入react(2-1)-Context

9天深入react(2-1)-Context

作者: 申_9a33 | 来源:发表于2021-02-14 14:00 被阅读0次

    组件跨层级通讯-Context

    Context API

    • React.createContext 创建一个Context对象
    • Context.Provider Provider 接受一个Value属性,传递给消费组件,当Provider 的Value值发生辩护时,它内部的所有消费组件都会重新渲染,Provider及其内部的consumer 组件都不受制于shouldComponentUpdate函数,因此当consumer组件载器祖先组件退出更新的情况下也能更新
    • Class.contextType 挂在clss 上的contextType属性会被重新复制为有React.createContext创建的Context对象,这可以让你使用 this.context来消费最近Context上的那个值。可以在任何生命周期函数中访问,包括render函数中
    • Context.Consumer 返回一个React节点,传递给函数的value值等同于往上组件树里这个context最近的Provider提供的Value值

    第一步,创建一个ThemeContext.ts管理上下文,用于生产数据和消费数据

    // ThemeContext.ts
    
    import React from 'react'
    
    //  创建context 
    export const ThemeContext = React.createContext({ themeColor: "pink" });
    // 接收者
    export const ThemeProvider = ThemeContext.Provider;
    // 消费者
    export const ThemeConsumer = ThemeContext.Consumer;
    

    第二步,消费数据

    • 方式一:使用 Class.contextType 方式消费

      • 重点是 static contextType = ThemeContext; 加上它就可以在任何生命周期中访问到this.context
    // ContextTypePage.tsx
    
    import React, { Component } from 'react'
    import { ThemeContext } from '../ThemeContext'
    
    export default class ContextTypePage extends Component {
        static contextType = ThemeContext;
    
        render() {
    
            const { themeColor } = this.context;
    
            return (
                <div className="border">
                    <h3 className={themeColor}>
                        ContextTypePage
                    </h3>
                </div>
            )
        }
    }
    
    
    
    • 方式二:使用 Context.Consumer 方式消费

    // ConsumerPage.tsx
    
    import React, { Component } from 'react'
    import { ThemeConsumer } from '../ThemeContext'
    
    export default function ConsumerPage() {
        return (
            <div className="border">
                <h3>ConsumerPage</h3>
                <ThemeConsumer>
                    {ctx => <div className={ctx.themeColor}>文本</div>}
                </ThemeConsumer>
            </div>
        );
    }
    

    第三步生产数据

    // ContextPage.tsx
    
    import React, { Component } from 'react'
    import { ThemeProvider } from '../ThemeContext'
    import ConsumerPage from '../pages/ConsumerPage'
    import ContextTypePage from '../pages/ContextTypePage'
    
    // 使用contetx步骤
    // 1. 创建 createContext
    // 2. Proiver接收value,以保证有传下去的数据
    // 3. 接收 Consumer或者class.contextType
    
    export default class ContextPage extends Component {
    
        state: {
            theme: {
                themeColor: string
            }
        }
    
        constructor(props: any) {
            super(props);
    
            this.state = {
                theme: {
                    themeColor: "red"
                }
            }
        }
    
        changeColor = () => {
            const { themeColor } = this.state.theme;
    
            this.setState({
                theme: {
                    themeColor: themeColor === "red" ? "green" : "red"
                }
            })
        }
    
    
        render() {
    
            const { theme} = this.state;
            return (
                <div className="App">
                    <button onClick={this.changeColor}>changeColor</button>
                    <button onClick={this.changeName}>changeName</button>
                </div>
            )
        }
    }
    
    

    消费多个Context

    第一步在上述案例中补充一个 context UserContext.ts

    // UserContext.ts
    
    import React from 'react'
    
    export const UserContext = React.createContext({name:"hotpinkBorder"});
    
    export const UserProvider = UserContext.Provider;
    
    export const UserConsumer = UserContext.Consumer;
    

    第二部增加一个消费多个context 的页面 MultipleContextPage.tsx

    // MultipleContextPage.tsx
    
    import React, { Component } from 'react'
    import { ThemeConsumer } from '../ThemeContext'
    import { UserConsumer } from '../UserContext'
    
    export default class MultipleContextPage extends Component {
        render() {
            return (
                <div>
                    <h3>MultipleContextPage</h3>
                    <ThemeConsumer>
                        {themeCtx => (
                            <UserConsumer>
                                {
                                    userCtx =>
                                        <div>
                                            <div>themeCtx:{themeCtx.themeColor}</div>
                                            <div>userCtx:{userCtx.name}</div>
                                        </div>
                                }
                            </UserConsumer>
                        )}
                    </ThemeConsumer>
                </div>
            )
        }
    }
    

    生产多个context ,用于消费

    // ContextPage.tsx
    
    import React, { Component } from 'react'
    import { ThemeProvider } from '../ThemeContext'
    import { UserProvider } from '../UserContext'
    import ConsumerPage from '../pages/ConsumerPage'
    import ContextTypePage from '../pages/ContextTypePage'
    import MultipleContextPage from './MultipleContextPage'
    
    // 使用contetx步骤
    // 1. 创建 createContext
    // 2. Proiver接收value,以保证有传下去的数据
    // 3. 接收 Consumer或者class.contextType
    
    export default class ContextPage extends Component {
    
        state: {
            theme: {
                themeColor: string
            },
            user: {
                name: string
            }
        }
    
        constructor(props: any) {
            super(props);
    
            this.state = {
                theme: {
                    themeColor: "red"
                },
                user: {
                    name: "xiaoming"
                }
            }
        }
    
        changeColor = () => {
            const { themeColor } = this.state.theme;
    
            this.setState({
                theme: {
                    themeColor: themeColor === "red" ? "green" : "red"
                }
            })
        }
    
        changeName = () => {
            const { name } = this.state.user
    
            this.setState({
                user: {
                    name: name === "xiaoming" ? "小明" : "xiaoming"
                }
            })
        }
    
        render() {
    
            const { theme, user } = this.state;
            return (
                <div className="App">
                    <button onClick={this.changeColor}>changeColor</button>
                    <button onClick={this.changeName}>changeName</button>
    
                    <ThemeProvider value={theme}>
                        <ContextTypePage />
                        <ConsumerPage />
    
                        <UserProvider value={user}>
                            <MultipleContextPage />
                        </UserProvider>
                    </ThemeProvider>
                </div>
            )
        }
    }
    
    

    源码


    相关文章

      网友评论

        本文标题:9天深入react(2-1)-Context

        本文链接:https://www.haomeiwen.com/subject/kqlyxltx.html