React--Context的使用

一、为什么要用context

Context 提供了一个无需为每层组件手动添加 props,就能在组件树间进行数据传递的方法。

当我们子组件很多,并且都在同一个组件树上时,我们需要把props传递非常多次,所有我们可以用context把一些每个组件的公共数据通过Provider传递。

Context 设计目的是为了共享那些对于一个组件树而言是“全局”的数据。

二、如何使用Context?

详情参考官网

(1) Reract官方给出的API :
React.createContext:创建一个上下文的容器(组件), defaultValue可以设置共享的默认数据

const defaultContext = React.createContext(defaultValue); // 没解构Provider和Consumer,后面可以通过 . 的方式设置。适用于多个context时候
const {Provider, Consumer} = React.createContext(defaultValue); // 直接解构出Provider和Consumer,适用于只有一个context的时候

(2) Provider(生产者): 用于生产共享数据的地方。生产什么呢? 那就看value定义的是什么了。value:放置共享的数据。

<Provider value={/*共享的数据*/}>
    /*里面可以渲染对应的内容*/
</Provider>

(3) Consumer(消费者):这个可以理解为消费者。 他是专门消费供应商(Provider 上面提到的)产生数据。Consumer需要嵌套在生产者下面。才能通过回调的方式拿到共享的数据源。当然也可以单独使用,那就只能消费到上文提到的defaultValue

<Consumer>
  {value => ()/*根据上下文  进行渲染相应内容*/}
</Consumer>
1.使用Context
const ThemeContext = React.createContext('red')
class App extends React.Component {
    render() {
        return (
            // 01-Provider 将theme主题 通过value属性传递给 所有子元素 子组件的props.children        
            // Provider是一个组件,允许消费组件 订阅context变化
            // Provider value属性值发生变化,内部所有的消费组件都会重新渲染
            // 若组件树中,没有匹配到provider,则 使用默认值 defaultValue
            <ThemeContext.Provider value="green">
                <Toolbar_1 />
            </ThemeContext.Provider>
        )
    }
}
class Toolbar_1 extends extends React.Component {
    render(){
        return (
        // 03-通过Consumer 订阅context的变更
        // 使用 函数作为子元素,函数参数 就是当前的context的值(provider value属性值)
        // 函数返回值就是react的一个结点元素
            <ThemeContext.Consumer>
                {
                    (value) => {
                        return (
                            <div>
                                <div style={{ color: value }}>Toolbar</div>
                                <ThemeButton theme={value} />
                            </div>
                        )
                    }
                }
            </ThemeContext.Consumer>
        )
    }
}
// 02-使用contextType
// 只能在类组件内使用,函数组件内使用 不好使
// 但是<Consumer>在函数组件和类组件内都可以使用
class Toolbar_2 extends React.Component {
    // 也可以使用默认属性赋值
    static contextType = ThemeContext
    render() {
        return (
            <div>
                <div style={{ color: this.context }}>Toolbar</div>
                <ThemeButton theme={this.context} />
            </div>
        )
    }
}
// Toolbar.contextType = ThemeContext  // this.context = context

class ThemeButton extends React.Component {
    render() {
        return (
            <ThemeContext.Consumer>
                {
                    (value) => (
                            <button style={{ color: value }}>主题按钮</button>
                        )
                }
            </ThemeContext.Consumer>
        )
    }
}
2.动态使用Context

当我们传递个value的值为state时,我们state更新,value也会跟着更新,从而实现动态使用context的效果

// 动态使用context
// 01-定义主题
const themes = {
    light: {
        color: "red",
        background: "#fff"
    },
    dark: {
        color: "green",
        background: "#000"
    }
}
// 02-定义context
const ThemeContext = React.createContext(themes.dark)
// 03-提供provider
class App extends React.Component {
    constructor(props) {
        super(props)
        // theme 被定义成状态维护的主题 动态的值
        this.state = {
            theme:themes.light
        }
    }
    toggleTheme = ()=>{
        // 注意 state 对原有状态 有依赖
         this.setState((preState)=>{
            return {
                theme:preState.theme === themes.light ? themes.dark : themes.light
            }
        })
    }
// provider value 和 thi.state 有关联后
// 通过setState改变value值回触发重新渲染,所有的子组件都会重新渲染(重要),shouldComponentUpdate有效
    render() {
        return (
            <ThemeContext.Provider value={this.state.theme}>
                <Toolbar changeTheme={this.toggleTheme}/>
            </ThemeContext.Provider>
        )
    }
}
class Toolbar extends React.Component {
    static contextType = ThemeContext
    render() {
        let {changeTheme} = this.props
        let { color, background } = this.context
        return (
            <div>
                <div style={{ color: color, background: background }}>ToolBar</div>
                <ThemeButton {...this.props}/>
            </div>
        )
    }
}
class ThemeButton extends React.Component {
    static contextType = ThemeContext
    render() {
        let {changeTheme} = this.props
        let { color, background } = this.context
        return (
            <button style={{color, background}} onClick={changeTheme}>主题按钮</button>
        )
    }
}
3.当多个context同时使用时

当有多个context,contextType不好使了,要用Consumer嵌套。

当然后面还有更好的办法useContext,不过只能适用于函数组件。

useContext的使用

class App extends React.Component {
    state = {
        age:60
    }
    handleChange = ()=>{
        this.setState({
            age:this.state.age = 80
        })
    }
    render(){
        return (
            <div>
                <h2>app:{this.state.age}</h2>  
                <Father/>  
                <button onClick={this.handleChange}>Change Age</button>
            </div>
        )
    }
}

const MoneyContext = React.createContext(50)
const HouseContext = React.createContext("house")
class Father extends React.Component {
    state = {
        money: 100,
        house: "apartment"
    }
    render() {
        // 出现多个context传递数据,可以使用Provider进行嵌套
        return (
            <MoneyContext.Provider value={this.state.money}>
                <HouseContext.Provider value={this.state.house} >
                    <Son />
                </HouseContext.Provider>
            </MoneyContext.Provider>
        )
    }
}
function Son() {
    return (
        <MoneyContext.Consumer>
            {
                (money) => {
                    return (
                        <div>
                            <p>Son组件,获取father值为:{money}</p>
                            <br />
                            <GrandSon />
                        </div>
                    )
                }
            }
        </MoneyContext.Consumer>
    )
}
function GrandSon() {
    // Consumer 包裹内容时,只能是一个函数,不能直接是一个组件
    // 多个Context 时候,可以使用嵌套函数
    return (
        <MoneyContext.Consumer>
            {
                (money) => (
                    <HouseContext.Consumer>
                        {
                            (house) => (
                                <div>
                                    <p>GrandSon组件,获取father的钱为:{money}</p>
                                    <p>GrandSon组件,获取father的房子为:{house}</p>
                                </div>
                            )
                        }
                    </HouseContext.Consumer>
                )
            }
        </MoneyContext.Consumer>
    )
}
// class GrandSon extends React.Component {
//     // contextType使用条件:
//     // 01-类组件
//     // 02-只有一个context时,如果有多个context时会后面的覆盖前面的,所以多个时直接使用consumer嵌套
//     static contextType = MoneyContext
//     static contextType = HouseContext
//     render() {
//         console.log(contextType);
//         let {house,money} = this.context // 不行,不能拿两个,只能拿到后面的
//         return (
//             <div>
//                 <p>GrandSon组件,获取father的钱为:{money}</p>
//                 <p>GrandSon组件,获取father的房子为:{house}</p>
//             </div>
//         )                  
//     }
// }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
React Native提供了一些用于缩放图片的组件,其之一是`react-native-safe-area-context`库的`SafeAreaImage`组件。这个组件可以帮助你在设备边缘安全区域内展示图片,并允许你进行缩放操作。 要使用`SafeAreaImage`组件进行图片缩放,你可以按照以下步骤进行操作: 1. 首先,确保你已经安装了`react-native-safe-area-context`库。你可以使用npm或yarn进行安装: ```bash npm install react-native-safe-area-context ``` 或 ```bash yarn add react-native-safe-area-context ``` 2. 在你的React Native应用程序引入`SafeAreaImage`组件: ```javascript import SafeAreaImage from 'react-native-safe-area-context'; ``` 3. 在需要展示缩放图片的组件使用`SafeAreaImage`组件,并设置相关属性。例如,你可以使用`style`属性设置图片的尺寸和位置,使用`resizeMode`属性设置图片的缩放模式,以及使用`source`属性设置图片的来源。 ```javascript <SafeAreaImage style={{ width: 200, height: 200 }} resizeMode="center" source={require('./path/to/your/image.png')} /> ``` 在上面的示例,我们设置了图片的宽度和高度为200像素,并使用`resizeMode="center"`将图片居显示。我们还通过`source`属性指定了图片的来源路径。 需要注意的是,上述示例的路径是一个相对路径,你需要根据实际情况修改为你的图片文件的实际路径。另外,你还可以根据需要设置其他样式和属性来定制缩放图片的外观和行为。 除了`react-native-safe-area-context`库提供的`SafeAreaImage`组件,React Native还提供了其他一些用于缩放图片的组件和第三方库,如`react-native-responsive-image`、`react-native-safe-area-image`等。你可以根据需要选择适合你的库或组件来进行图片缩放操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值