我正在尝试使用React Context更新我的Web应用程序的登录/注销功能。由于这不是一个高流量函数,因此我认为这是使用上下文API,创建我的提供程序并利用链中必要组件中的提供程序的绝佳机会。
不幸的是,看来我无法在组件函数中使用任何传递的函数,例如handleSubmit()。如果我直接从DOM元素中调用它们(它们在下面的示例中),它们的效果很好。
我认为这是某种“ this”错误,并且DOM调用使用的范围与组件中使用的范围不同。
任何有关为什么发生这种情况以及如何解决它的帮助都将非常有用。
谢谢!
上下文:
export const LoginContext = React.createContext({});
export class LoginCtx extends Component {
constructor(props) {
super(props);
this.state = {
isLoggedIn: false,
login: () => this.login,
logout: () => this.logout
};
this.login = this.login.bind(this);
this.logout = this.logout.bind(this);
}
login(user) {
console.log('Inside Login:', user);
this.setState({ isLoggedIn: true });
}
logout() {
console.log('Inside Logout');
this.setState({ isLoggedIn: false });
}
render() {
return (
<LoginContext.Provider value={this.state}>
{this.props.children}
</LoginContext.Provider>
);
}
}
表格:
const C = ({ classes }) => {
const { login } = useContext(LoginContext);
const initialValues = {
email: 'abc@test.com',
password: '',
remember: false
};
const dummySubmit = async (values, actions) => {
console.log(JSON.stringify(values, null, 2));
if (values.email === 'abc@test.com') {
// THIS ONE WONT FIRE THE LOGIN COMMAND
login();
}
actions.setSubmitting(false);
};
return (
<React.Fragment>
<Formik
initialValues={initialValues}
onSubmit={(values, actions) => dummySubmit(values, actions)}
>
{({ isSubmitting }) => (
<Form className={classes.form}>
<div>
<Field
name='email'
type='email'
placeholder='Email'
/>
<ErrorMessage name='email' component='div' />
</div>
<div>
<Field
name='password'
type='password'
placeholder='Password'
/>
<ErrorMessage name='email' component='div' />
</div>
<button type='submit' disabled={isSubmitting}>
Login
</button>
</Form>
)}
</Formik>
{/* THIS ONE DOES FIRE THE LOGIN COMMAND */}
<button onClick={login()}>Login Ctx</button>
</React.Fragment>
);
};
答案 0 :(得分:0)
this.state = {
isLoggedIn: false,
login: () => this.login,
logout: () => this.logout
};
您在此处创建的函数除了返回对this.login
/ this.logout
的引用外没有任何作用。就目前而言,位于组件树下方的组件必须调用从上下文中获取的函数,然后调用由第一次调用返回的函数。例如:
const { login } = useContext(LoginContext);
// ...
login()();
您很可能打算这样做:
this.state = {
isLoggedIn: false,
login: () => this.login(),
logout: () => this.logout()
};
this.login = this.login.bind(this);
this.logout = this.logout.bind(this);
或者这个:
this.login = this.login.bind(this);
this.logout = this.logout.bind(this);
this.state = {
isLoggedIn: false,
login: this.login,
logout: this.logout
};