Now*_*yed 19 javascript reactjs react-context
MyContext.js
import React from "react";
const MyContext = React.createContext('test');
export default MyContext;
Run Code Online (Sandbox Code Playgroud)
创建了一个上下文单独的js文件,我可以在父文件和子组件中访问它
Parent.js
import MyContext from "./MyContext.js";
import Child from "./Child.js";
class Parent extends Component {
constructor(props) {
super(props);
this.state = {
Message: "Welcome React",
ReturnMessage:""
};
}
render() {
return (
<MyContext.Provider value={{state: this.state}}>
<Child />
</MyContext.Provider>
)
}
}
Run Code Online (Sandbox Code Playgroud)
因此,在Provider选项卡中创建了一个父组件,其中包含Provider上下文和调用子组件
Child.js
import MyContext from "./MyContext.js";
class Child extends Component {
constructor(props) {
super(props);
this.state = {
ReturnMessage:""
};
}
ClearData(context){
this.setState({
ReturnMessage:e.target.value
});
context.state.ReturnMessage = ReturnMessage
}
render() {
return (
<MyContext.Consumer>
{(context) => <p>{context.state.Message}</p>}
<input onChange={this.ClearData(context)} />
</MyContext.Consumer>
)
}
}
Run Code Online (Sandbox Code Playgroud)
因此在使用消费者的孩子可以显示在子渲染部分..
我正面临从消费者到提供者状态的更新.
如何更新提供者状态或操纵提供者的状态..
小智 40
您可以使用 useContext 钩子来实现这一点。在 Provider 的子元素中使用它非常容易。举个例子...
authContext.js
import { createContext } from "react";
const authContext = createContext({
authenticated: false,
setAuthenticated: (auth) => {}
});
export default authContext;
Run Code Online (Sandbox Code Playgroud)
Login.js(使用上下文的组件)
import React, { useContext } from "react";
import authContext from "./authContext";
export default () => {
const { setAuthenticated } = useContext(authContext);
const handleLogin = () => setAuthenticated(true);
const handleLogout = () => setAuthenticated(false);
return (
<React.Fragment>
<button onClick={handleLogin}>login</button>
<button onClick={handleLogout}>logout</button>
</React.Fragment>
);
};
Run Code Online (Sandbox Code Playgroud)
最后是 index.js
import ReactDOM from "react-dom";
import React, { useState } from "react";
import authContext from "./authContext";
import Login from "./Login";
const App = () => {
const [authenticated, setAuthenticated] = useState(false);
return (
<authContext.Provider value={{ authenticated, setAuthenticated }}>
<div> user is {`${authenticated ? "" : "not"} authenticated`} </div>
<Login />
</authContext.Provider>
);
};
ReactDOM.render(<App />, document.getElementById("container"));
Run Code Online (Sandbox Code Playgroud)
如您所见,使用 useContext 钩子使用存储在上下文中的数据变得非常容易。当然,就像每个 React 钩子一样,它只适用于函数式组件。
如果你想看到代码工作。 https://codesandbox.io/s/react-playground-forked-wbqsh?file=/index.js
Jac*_*ack 33
通常需要从嵌套在组件树深处某处的组件更新上下文。在这种情况下,您可以通过上下文向下传递函数以允许消费者更新上下文:
主题上下文.js
// Make sure the shape of the default value passed to
// createContext matches the shape that the consumers expect!
export const ThemeContext = React.createContext({
theme: themes.dark,
toggleTheme: () => {},
});
Run Code Online (Sandbox Code Playgroud)
主题切换器-button.js
import {ThemeContext} from './theme-context';
function ThemeTogglerButton() {
// The Theme Toggler Button receives not only the theme
// but also a toggleTheme function from the context
return (
<ThemeContext.Consumer>
{({theme, toggleTheme}) => (
<button
onClick={toggleTheme}
style={{backgroundColor: theme.background}}>
Toggle Theme
</button>
)}
</ThemeContext.Consumer>
);
}
export default ThemeTogglerButton;
Run Code Online (Sandbox Code Playgroud)
应用程序.js
import {ThemeContext, themes} from './theme-context';
import ThemeTogglerButton from './theme-toggler-button';
class App extends React.Component {
constructor(props) {
super(props);
this.toggleTheme = () => {
this.setState(state => ({
theme:
state.theme === themes.dark
? themes.light
: themes.dark,
}));
};
// State also contains the updater function so it will
// be passed down into the context provider
this.state = {
theme: themes.light,
toggleTheme: this.toggleTheme,
};
}
render() {
// The entire state is passed to the provider
return (
<ThemeContext.Provider value={this.state}>
<Content />
</ThemeContext.Provider>
);
}
}
function Content() {
return (
<div>
<ThemeTogglerButton />
</div>
);
}
ReactDOM.render(<App />, document.root);
Run Code Online (Sandbox Code Playgroud)
上面的示例直接来自 React Context API docs v16.8.6,并且是从使用者更新上下文值的推荐方法。https://reactjs.org/docs/context.html#updating-context-from-a-nested-component
Shu*_*tri 15
首先,为了从使用者那里更新上下文,您需要在render函数之外访问上下文,有关如何执行此操作的详细信息,请检查
其次,您应该从Provider提供一个处理程序,该处理程序将更新上下文值,而不是直接对其进行更改。您的代码看起来像
Parent.js
import MyContext from "./MyContext.js";
import Child from "./Child.js";
class Parent extends Component {
constructor(props) {
super(props);
this.state = {
Message: "Welcome React",
ReturnMessage:""
};
}
updateValue = (key, val) => {
this.setState({[key]: val});
}
render() {
return (
<MyContext.Provider value={{state: this.state, updateValue: this.updateValue}}>
<Child />
</MyContext.Provider>
)
}
}
Run Code Online (Sandbox Code Playgroud)
儿童
import MyContext from "./MyContext.js";
class Child extends Component {
constructor(props) {
super(props);
this.state = {
ReturnMessage:""
};
}
ClearData(e){
const val = e.target.value;
this.setState({
ReturnMessage:val
});
this.props.context.updateValue('ReturnMessage', val);
}
render() {
return (
<React.Fragment>
<p>{this.props.context.state.Message}</p>}
<input onChange={this.ClearData} />
</React.Fragment>
)
}
}
const withContext = (Component) => {
return (props) => {
<MyContext.Consumer>
{(context) => {
return <Component {...props} context={context} />
}}
</MyContext.Consumer>
}
}
export default withContext(Child);
Run Code Online (Sandbox Code Playgroud)
您需要在Provider组件中编写一个函数来更新State。确切地说,Consumer 只能使用您在 Provider 组件中编写的值和函数。
在父组件中
updateReturnMessage = (ReturnMessage) => {
this.setState((prevState) => ({ ...prevState, ReturnMessage }))
}
<MyContext.Provider value={{ state: this.state, updateReturnMessage: this.updateReturnMessage }}>
// your code goes here
</MyContext.Provider>
Run Code Online (Sandbox Code Playgroud)
在子组件中:
ClearData(e){
const val = e.target.value;
this.context.updateReturnMessage(val);
}
Run Code Online (Sandbox Code Playgroud)
此功能类似于和action creators中的可用功能Reduxflux
| 归档时间: |
|
| 查看次数: |
17849 次 |
| 最近记录: |