Context
React Context 详解
Context 基本使用
const ThemeContext = React.createContext("dark");
export const { Consumer, Provider } = ThemeContext;
// This is a HOC function.
// It takes a component...
export default function withTheme(Component) {
// ...and returns another component...
return function ThemedComponent(props) {
// ... and renders the wrapped component with the context theme!
// Notice that we pass through any additional props as well
return (
<Consumer>{(theme) => <Component {...props} theme={theme} />}</Consumer>
);
};
}
function Header({ children, theme }) {
return <h1 className={`header-${theme}`}>{children}</h1>;
}
// Use the withTheme HOC to inject the context theme,
// Without having to bloat our component to reference it:
export default withTheme(Header);
HoC 封装
Hooks 封装
老版本的Context API
Context
,我们需要引入 contextTypes
、getChildContext
、childContextTypes
这三个属性:
this.context
的值内容,因此我们需要在这里设置子函数能够返回的属性信息。
getChildContext
返回值的数据结构,其会起到类似于 propTyps
这样的类型校验功能。
参考
import PropTypes from "prop-types";
class Button extends React.Component {
render() {
return (
<button style={{ background: this.context.color }}>
{this.props.children}
</button>
);
}
}
Button.contextTypes = {
color: PropTypes.string,
};
class Message extends React.Component {
render() {
return (
<div>
{this.props.text} <Button>Delete</Button>
</div>
);
}
}
class MessageList extends React.Component {
getChildContext() {
return { color: "purple" };
}
render() {
const children = this.props.messages.map((message) => (
<Message text={message.text} />
));
return <div>{children}</div>;
}
}
MessageList.childContextTypes = {
color: PropTypes.string,
};
通过为
-
老版本的
Context API 允许以Props 方式透传,其问题在于破坏了组件本身的可移植性,或者说是分形架构,增强了组件间的耦合度。所谓的分形架构,即组件树中的任一部分能够被独立抽取使用,并且方便移植到其他组件树中。( 参考诚身的回答) -
尽管其可以减少逐层传递带来的冗余代码,尽量的解耦和组件,但是当构造复杂时,我们也会陷入抽象漏洞,无法去判断
Context
到底是哪个父组件提供的。此时Context
就像所谓的全局变量一样,大量的全局变量的使用会导致组件的不可以预测性,导致整个系统的鲁棒性降低。 -
Context
并不会触发组件重渲染,如果组件树中的某个组件的shouldComponentUpdate
函数返回false
而避免了子层组件的重渲染,那么新的Context 值也就无法传递到子层组件,而导致目标组件无法保证自己每次都可以接收到更新后的Context 值。