我希望获得帮助,以了解如何从props
组件的function
内部将child
传递给上下文提供程序。
我有一个全局提供程序,我想从表单中保存data
,如果error
失败,则要保存onSubmit
数据。
使用createContext
我有一家全球服务提供商
import React, { createContext } from 'react';
interface InterfaceProps {
children?: any;
}
interface InterfaceState {
error: any;
toggleAuthError: any;
}
const GlobalContext = createContext({
error: null,
toggleAuthError: () => {}
});
export class GlobalProvider extends React.Component<InterfaceProps, InterfaceState> {
public toggleAuthError = ({ authError }: any) => {
this.setState({ error: authError });
};
public state = {
error: null,
toggleAuthError: this.toggleAuthError
};
public render() {
const { children } = this.props;
return <GlobalContext.Provider value={this.state as any}>{children}</GlobalContext.Provider>;
}
}
export const GlobalConsumer = GlobalContext.Consumer;
然后在表单child
组件中,我有一个名为onSubmit
的函数。
public handleFormSubmit = async (data: { email: string; password: string }) => {
const { form } = this.props;
const { email, password } = data;
await form
...
.catch((error: any) => {
toggleAuthError(error); // Want this to trigger the function and pass error to the context provider
this.setState({
loading: false
});
});
};
如何在上下文提供程序中将error
传递给this.toggleAuthError
?
答案 0 :(得分:1)
您应该使用GlobalConsumer包装您的子组件,以便访问上下文值。像这样:
<MyContext.Consumer>
{({toggleAuthError}) => /* render something based on the context value */}
</MyContext.Consumer>
然后,您只需将toggleAuthError
传递到handleFormSubmit函数。
答案 1 :(得分:1)
如Ovidiu所指出的,如果您的组件是功能组件,那么使用Context.Consumer
很好。
但是,如果您的组件扩展了React.Component,则可以使用Context.contextType
。这样,您就可以使用this.context
来消耗该Context类型的最近值。
使用此设置,您可以在回调函数中访问toggleAuthError
方法。
对于您的情况,在child
组件(如果是Class)中,您将使用:
static contextType = GlobalContext;
,然后可以使用toggleAuthError
访问this.context.toggleAuthError
方法。
以下示例显示了两种方法-Context.contextType
和Context.Consumer
来使用上下文的两个部分(error
和toggleAuthError
)。
const GlobalContext = React.createContext({
error: 0,
toggleAuthError: () => {}
});
class GlobalProvider extends React.Component {
constructor(props) {
super(props);
this.toggleAuthError = (newError) => {
this.setState(state => ({
error: newError
}))
};
this.state = {
error: 0,
toggleAuthError: this.toggleAuthError,
};
}
render() {
return (
<GlobalContext.Provider value={this.state}>
{this.props.children}
</GlobalContext.Provider>
)
}
}
const Form = () => {
return (
<div>
<ToggleAuthErrorButton />
<Error />
</div>
)
}
// A React component which uses context using Context.contextType
class ToggleAuthErrorButton extends React.Component {
static contextType = GlobalContext;
toggleError = () => {
return this.context.toggleAuthError(this.context.error + 1);
}
render() {
return (
<button onClick={this.toggleError}>Toggle Auth Error</button>
)
}
}
// A function component which uses context using Context.Consumer
const Error = () => {
return (
<GlobalContext.Consumer>
{({error}) => {
return (
<div>Error {error}</div>
)
}}
</GlobalContext.Consumer>
)
}
class App extends React.Component {
render(){
return (
<GlobalProvider>
<Form />
</GlobalProvider>
)
}
}
ReactDOM.render(<App />, document.getElementById('root'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.0/umd/react-dom.production.min.js"></script>
<div id="root"></div>