Метод доступа к React Context API из детского метода
Я новичок в React и пытаюсь создать контекстный API. Я читал аналогичный вопрос, но не могу найти решения.
Мой файл поставщика контекста:
import React, { Component } from 'react'
const MyContext = React.createContext();
class ContextProvider extends Component {
constructor(props) {
super(props)
this.state = {
isLogin: false
}
}
handleLogin = () => {
this.setState({
isLogin : true
})
}
render() {
return (
<MyContext.Provider value={{
...this.state,
handleLogin : this.handleLogin
}}>
{this.props.children}
</MyContext.Provider>
);
}
}
const ContextConsumer = MyContext.Consumer;
export {ContextProvider, ContextConsumer};
Мне нужно изменить состояние, обратившись к handleLogin() в ContextProvider.js после успешного входа пользователя в систему:
import React, { Component } from 'react'
import {ContextConsumer} from "./ContextProvider";
class Login extends Component {
onHandleSubmit = () => {
// on submit login success :
// --- how to call handleLogin() in ContextProvider.js here ? ----
}
render() {
return (
<div> --- not expected here ---- </div>
)
}
}
Кстати, извините за мой английский.
1 ответ
Решение
Предполагая, что ваш компонент входа в систему заключен в ContextProvider
выше в иерархии вы можете получить доступ к контексту внутри компонента класса, определив статический contextType .
Для этого вам нужно сначала экспортировать контекст из ContextProvider, например
export {ContextProvider, ContextConsumer, MyContext };
а затем используйте его как
import React, { Component } from 'react'
import {MyContext} from "./ContextProvider";
class Login extends Component {
static contextType = MyContext;
onHandleSubmit = () => {
// on submit login success :
this.context.handleLogin();
}
render() {
return (
<div> {/* render content here */} </div>
)
}
}
Однако, если вы используете версию реакции между 16.3.0 и 16.6.0, вам необходимо передать контекст, используя шаблон рендеринга реквизита, например
class Login extends Component {
onHandleSubmit = () => {
// on submit login success :
this.props.context.handleLogin();
}
render() {
return (
<div> --- not expected here ---- </div>
)
}
}
export default (props) => (
<ContextConsumer>
{values=> <Login {...props} context={values} />}
</ContextConsumer>
)