旧的context
mport React from 'react';
import ReactDOM, { render } from 'react-dom'
import PropTypes from 'prop-types';
class App extends React.Component{
getChildContext() {
return {color: "purple"};
}
getChildContext(){
return {
color:"pusrplesss"
}
}
render(){
return <div>
<Father></Father>
</div>
}
}
App.childContextTypes ={
color: PropTypes.string
}
function Father(){
return <div>
<Child>
</Child>
</div>
}
class Child extends React.Component{
render(){
return <div>
得到context中的数据:{this.context.color}
</div>
}
}
Child.contextTypes = {
color: PropTypes.string
}
ReactDOM.render(<App/>, document.getElementById("root"))
旧的context实现跨组件传值主要依靠子组件定义contextTypes属性,父组件中定义childcontextTypes,以及还需要在父组件中定义context的值,这个值可以有getChildContext方法实现
注意:几乎没有什么合适的方式去改变context的值,所有不要轻易修改context中的数据
createContext:provider提供数据 consumer接收数据
import React from 'react';
import ReactDOM from 'react-dom'
let ContextThe = React.createContext('light');
class App extends React.Component {
render() {
return (
<ContextThe.Provider value="theme">
<Toolbar />
</ContextThe.Provider>
)
}
}
function Toolbar(props) {
return (
<ThemedButton />
);
}
function ThemedButton() {
return (
<ContextThe.Consumer>
{color => (
<div>
{color}
</div>
)}
</ContextThe.Consumer >
)
}
ReactDOM.render(<App />, document.getElementById("root"))
createContext会得到一个对象,这个对象包含Porvider和Consumer属性,Porvider提供数据,Consumer包含的子组件可以取得context中的值
context另外一种不使用Consumer方式
import React from 'react';
import ReactDOM from 'react-dom'
let ContextThe = React.createContext('light');
class App extends React.Component {
render() {
return (
<ContextThe.Provider value="theme">
<Toolbar />
</ContextThe.Provider>
)
}
}
function Toolbar(props) {
return (
<ThemedButton />
);
}
class ThemedButton extends React.Component {
static contextType = ContextThe;
render() {
return (
<div>
获取context中的值为:{this.context}
</div>
)
}
}
ReactDOM.render(<App />, document.getElementById("root"))
这种方式通过在子组件中给contextType赋值,便可以拿到context中的值
多个context一起使用
// Theme context,默认的 theme 是 “light” 值
const ThemeContext = React.createContext('light');
// 用户登录 context
const UserContext = React.createContext({
name: 'Guest',
});
class App extends React.Component {
render() {
const {signedInUser, theme} = this.props;
// 提供初始 context 值的 App 组件
return (
<ThemeContext.Provider value={theme}>
<UserContext.Provider value={signedInUser}>
<Layout />
</UserContext.Provider>
</ThemeContext.Provider>
);
}
}
function Layout() {
return (
<div>
<Sidebar />
<Content />
</div>
);
}
// 一个组件可能会消费多个 context
function Content() {
return (
<ThemeContext.Consumer>
{theme => (
<UserContext.Consumer>
{user => (
<ProfilePage user={user} theme={theme} />
)}
</UserContext.Consumer>
)}
</ThemeContext.Consumer>
);
}
可以通过嵌套消费者和提供者的方式实现一个消费者使用多个context中的数据
使用createConext,如何修改context的值
class App extends React.Component {
constructor(){
this.state = {
info:''
}
}
render() {
const {signedInUser, theme} = this.props;
// 提供初始 context 值的 App 组件
return (
<ThemeContext.Provider value={{
info:this.state.info,
changeInfo:(value)=>{this.setState({info:value}))
}}>
<UserContext.Provider value={signedInUser}>
<Layout />
</UserContext.Provider>
</ThemeContext.Provider>
);
}
}
想要修改获取context的数据,只需要利用state和setState即可,然后在consumer中调用changeInfo方法即可。
使用useContext代替consumer,是子组件能够访问到context数据
function Counter(){
const count = useContext(CountContext) //得到count
return (<h2>{count}</h2>)
}
const CountContext = createContext()
function App(){
const [ count , setCount ] = useState(0);
return (
<div>
<p>你点击了{count} 次</p>
<button onClick={()=>{setCount(count+1)}}>点击</button>
<CountContext.Provider value={count}>
{/*======引入子组件*/}
<Counter />
</CountContext.Provider>
</div>
)
}
export default App;