# 大纲
Context大纲 (opens new window) 密码:3279
# 老版本中的context
import propsTypes from 'proptypes';
import React, { Component } from 'react';
// 提供者
export default class ProviderDemo extends Component {
getChildContext() {
const info = {
name: 'f',
age: 18
};
return { info };
}
render() {
return <ConsumerDemo />;
}
}
ProviderDemo.childContextTypes = {
info: propsTypes.object
};
// 消费者
class ConsumerDemo extends Component {
render() {
const { name, age } = this.context.info;
return (
<div>
姓名:{name} 年龄:{age}
</div>
);
}
}
ConsumerDemo.contextTypes = {
info: propsTypes.object
};
# 新版本中的context
# 提供者
# 消费者
方式一:contextType
这种方式只能在类组件中使用。
import React, { createContext, Component } from 'react';
const UserInfoContext = createContext(null);
const UserInfoProvider = UserInfoContext.Provider;
export default class ProviderDemo extends Component {
state = {
name: 'f',
age: 18
};
render() {
return (
<UserInfoProvider value={this.state}>
<ConsumerDemo />
</UserInfoProvider>
);
}
}
// 消费者
class ConsumerDemo extends Component {
render() {
const { name, age } = this.context;
return (
<div>
name:{name} age:{age}
</div>
);
}
}
ConsumerDemo.contextType = UserInfoContext;
方法二:useContext
这种方式,只能在函数组件中使用。
import React, { createContext, Component, useContext } from 'react';
const UserInfoContext = createContext(null);
const UserInfoProvider = UserInfoContext.Provider;
export default class ProviderDemo extends Component {
state = {
name: 'f',
age: 18
};
render() {
return (
<UserInfoProvider value={this.state}>
<ConsumerDemo />
</UserInfoProvider>
);
}
}
// 消费者
function ConsumerDemo() {
const { name, age } = useContext(UserInfoContext);
return (
<div>
name:{name} age:{age}
</div>
);
}
方法三:Consumer
这种方式,函数组件和类组件中都可以使用。
import React, { createContext, Component } from 'react';
const UserInfoContext = createContext(null);
const UserInfoProvider = UserInfoContext.Provider;
export default class ProviderDemo extends Component {
state = {
name: 'f',
age: 15
};
render() {
return (
<UserInfoProvider value={this.state}>
<ConsumerDemo />
</UserInfoProvider>
);
}
}
// 消费者 函数组件
// const UserInfoConsumer = UserInfoContext.Consumer;
// function ConsumerDemo() {
// return (
// <UserInfoConsumer>
// {({ name, age }) => (
// <div>
// name:{name} age:{age}
// </div>
// )}
// </UserInfoConsumer>
// );
// }
// 消费者 类组件
const UserInfoConsumer = UserInfoContext.Consumer;
class ConsumerDemo extends Component {
render() {
return (
<UserInfoConsumer>
{({ name, age }) => (
<div>
name:{name} age:{age}
</div>
)}
</UserInfoConsumer>
);
}
}
# 动态context
import React, { createContext, useContext, useState, memo } from 'react';
const UserContext = createContext(null);
const UserProvider = UserContext.Provider;
export default () => {
const [ contextValue, setContextValue ] = useState({ name: 'f', age: 17 });
return (
<div>
<UserProvider value={contextValue}>
<ConsumerDemo />
</UserProvider>
<button onClick={() => setContextValue({ ...contextValue, age: 18 })}>改变年龄</button>
</div>
);
};
const ConsumerDemo = memo(() => {
const { name, age } = useContext(UserContext);
return (
<div>
name: {name}, age: {age}
</div>
);
});
# context高阶用法
# 嵌套 Provider
import React, { createContext, memo, useState } from 'react';
const ThemeContext = createContext(null);
const LanguageContext = createContext(null);
const ThemeProvider = ThemeContext.Provider;
const LanguageProvider = LanguageContext.Provider;
const ThemeConsumer = ThemeContext.Consumer;
const LanguageConsumer = LanguageContext.Consumer;
const ConsumerDemo = memo(() => {
return (
<ThemeConsumer>
{(theme) => (
<LanguageConsumer>
{(language) => {
const { color, background } = theme;
return <div style={{ color, background }}>{language}</div>;
}}
</LanguageConsumer>
)}
</ThemeConsumer>
);
});
export default () => {
const [ language, setLanguage ] = useState('ch');
const [ theme, setTheme ] = useState({ color: 'red', background: 'orange' });
return (
<ThemeProvider value={theme}>
<LanguageProvider value={language}>
<ConsumerDemo />
</LanguageProvider>
</ThemeProvider>
);
};
# 逐层传递 Provider
import React, { createContext, useContext } from 'react';
const LanguageContext = createContext(null);
const LanguageProvider = LanguageContext.Provider;
const ConsumerDemo2 = () => {
const language = useContext(LanguageContext);
return <span>{language}</span>;
};
const ConsumerDemo1 = () => {
const language = useContext(LanguageContext);
return (
<div>
{language}
<LanguageProvider value="en">
<ConsumerDemo2 />
</LanguageProvider>
</div>
);
};
export default () => {
return (
<LanguageProvider value="ch">
<ConsumerDemo1 />
</LanguageProvider>
);
};
# 问答
context 与 props 和 react-redux 的对比?
context:
- 解决了 props 需要每一层都手动添加 props 的缺陷。
- 解决了改变 value ,组件全部重新渲染的缺陷。
react-redux 就是通过 Provider 模式把 redux 中的 store 注入到组件中的。