MyContext.js
import React from "react";
const MyContext = React.createContext('test');
export default MyContext;
创建了一个上下文单独的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>
)
}
}
因此创建了一个父组件,使用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>
)
}
}
因此在使用消费者的孩子中可以显示儿童渲染部分..
我正面临从消费者到提供者状态的更新。
如何更新提供者状态或操纵提供者状态..
答案 0 :(得分:5)
您可以使用useContext挂钩来实现此目的。在Provider的子元素中使用它非常容易。例如...
authContext.js
import { createContext } from "react";
const authContext = createContext({
authenticated: false,
setAuthenticated: (auth) => {}
});
export default authContext;
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>
);
};
最后是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"));
如您所见,使用useContext挂钩可以很容易地使用存储在上下文中的数据。当然,与每个React钩子一样,它仅适用于功能组件。
如果您想查看代码是否正常工作。 https://codesandbox.io/s/react-playground-forked-wbqsh?file=/index.js
答案 1 :(得分:4)
首先,为了从使用者更新上下文,您需要访问render函数之外的上下文。有关如何执行此操作的详细信息,请检查
Access React Context outside of render function
其次,您应该从Provider提供一个处理程序,它更新上下文值而不是直接改变它。您的代码看起来像
<强> Parent.js 强>
import(tidyverse)
ex %>%
group_by(lat, long) %>%
summarise(closest_clim = which.min(abs(lat - clim$lat) +
abs(long - clim$long))) %>%
mutate(alt = clim$alt[closest_clim],
x = clim$x[closest_clim],
y = clim$y[closest_clim])
# A tibble: 3 x 6
# Groups: lat [3]
lat long closest_clim alt x y
<dbl> <dbl> <int> <dbl> <dbl> <dbl>
1 40. 10. 4 0.0333 0. 1921.
2 55. 6. 1 0.0333 0. 1914.
3 60. 6. 10 0.0333 0. 1884.
子
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>
)
}
}
答案 2 :(得分:1)
通常有必要从嵌套在组件树中某个位置的组件更新上下文。在这种情况下,您可以在上下文中向下传递一个函数,以允许使用者更新上下文:
theme-context.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: () => {},
});
theme-toggler-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;
app.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);
上面的示例直接来自React Context API文档v16.8.6,是从使用者更新上下文值的推荐方法。 https://reactjs.org/docs/context.html#updating-context-from-a-nested-component
答案 3 :(得分:0)
您需要在Provider组件中编写一个函数以更新State。 确切地说,消费者只能使用您在Provider组件中编写的值和函数。
在父组件中
articles
在子组件中:
this.state.newsPaper.map(async (querypara) => {
const requstone = await fetch(`https:someapisources=${querypara}&apiKey=${api_key}`);
const dataone = await requstone.json();
// Concatenate articles from response (dataone) to array in state
this.setState({
articles: this.state.articles.concat(dataone.articles)
});
}
此功能类似于updateReturnMessage = (ReturnMessage) => {
this.setState((prevState) => ({ ...prevState, ReturnMessage }))
}
<MyContext.Provider value={{ state: this.state, updateReturnMessage: this.updateReturnMessage }}>
// your code goes here
</MyContext.Provider>
和ClearData(e){
const val = e.target.value;
this.context.updateReturnMessage(val);
}
中可用的action creators
答案 4 :(得分:-3)
@nowshad,您是否正在尝试使用redux 然后我建议使用提供者
import React from 'react'
import { render } from 'react-dom'
import { Provider } from 'react-redux'
import { createStore } from 'redux'
import todoApp from './reducers'
import App from './components/App'
const store = createStore(todoApp)
render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
)
如果您只使用少数几个组件,并且希望根据您的语句获得所有嵌套组件的值
For nested components can i have one provider and multiple consumers For an Example : 1 is an parent , 1.1 is a child to 1 and 1.1.1 is child to 1.1, Can i have provider to 1 and consumers to 1.1 and 1.1.1
然后我建议您只需将处理程序作为prop传递,一旦您想要更改状态调用处理程序,它将在整个组件中更改值。(如果您只有少数子组件,那么这应该完成在整个过程中需要相同的值
***Using context, we can avoid passing props through intermediate elements***
根据React Docs
不要仅使用上下文来避免将道具向下移动几级。棒 在许多组件中需要访问相同数据的情况 在多个层面。
检查官方文档,了解为何以及为何不使用Context: https://reactjs.org/docs/context.html
如果您对使用上下文的原因和方法仍有疑问或疑问,请与我们联系