React-context
1、Context 简介
Context 提供了一个传递数据的方法,避免了在每一个层级手动的传递 props 属性。
2、context API
1)React.createContext:
const {Provider, Consumer} = React.createContext(defaultValue);
2)Provider(提供者):
<Provider value={/* some value */}>
3)Consumer(消费者):
<Consumer>
{value => /* render something based on the context value */}
</Consumer
PS:
- 每当Provider的值发生改变时, 作为Provider后代的所有Consumers都会重新渲染。
- 从Provider到其后代的Consumers传播不受shouldComponentUpdate方法的约束,因此即使祖先组件退出更新时,后代Consumer也会被更新。
3、context 传递静态数据
就是引用公共的 React.createContext()创建的实例。
context.js
import React from "react";
export const ThemeContext = React.createContext(
themes.dark // 默认值
);
app.js(父级)
import { ThemeContext, themes } from "./context";
import Children from "./Children";
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
theme2: {
name: "theme2",
background: "red",
},
};
}
render() {
return (
<div>
<ThemeContext.Provider value={this.state.theme2}>
<Children></Children>
</ThemeContext.Provider>
</div>
);
}
}
export default App;
children.js(子级)
import React, { Component } from "react";
import { Context, ThemeContext } from "./context.js";
import Children2 from "./Children2";
class Children extends Component {
static contextType = Context;
render() {
return (
<ThemeContext.Consumer>
{(theme) => (
<div>
主题颜色(子组件):{theme.background}
<Children2></Children2>
</div>
)}
</ThemeContext.Consumer>
);
}
}
export default Children;
children2.js (孙级)
import React from "react";
import { ThemeContext } from "./context";
class Children2 extends React.Component {
render() {
return (
<ThemeContext.Consumer>
{(theme) => <div>主题Name(孙子组件):{theme.name}</div>}
</ThemeContext.Consumer>
);
}
}
export default Children2;
4、context 传递动态数据
context.js
import React from "react";
export const themes = {
light: {
name: "light",
background: "#222222",
},
dark: {
name: "dark",
background: "#eeeeee",
},
};
export const ThemeContext = React.createContext(
themes.dark // 默认值
);
app.js (父级&子级)
import { ThemeContext, themes } from "./context";
import ThemedButton from "./themed-button";
// 一个使用到ThemedButton组件的中间组件
function Toolbar(props) {
return <ThemedButton onClick={props.changeTheme}>Change Theme</ThemedButton>;
}
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
theme: themes.light
};
this.toggleTheme = () => {
this.setState((state) => ({
theme: state.theme === themes.dark ? themes.light : themes.dark,
}));
};
}
render() {
// ThemedButton 位于 ThemeProvider 内
// 在外部使用时使用来自 state 里面的 theme
// 默认 dark theme
return (
<div>
<ThemeContext.Provider value={this.state.theme}>
<Toolbar changeTheme={this.toggleTheme} />
</ThemeContext.Provider>
</div>
);
}
}
export default App;
themed-button.js(孙级)
import { ThemeContext } from "./context";
function ThemedButton(props) {
return (
<ThemeContext.Consumer>
{(theme) => (
<button
{...props}
style={{ backgroundColor: theme.background }}
/>
)}
</ThemeContext.Consumer>
);
}
export default ThemedButton;
按钮主题切换: