Как передать функцию из ФУНКЦИОНАЛЬНОГО в компонент КЛАССА и получить к нему доступ вне рендеринга (без опоры), используя контекст в React js?
Как передать функцию из ФУНКЦИОНАЛЬНОГО в компонент КЛАССА, используя контекст в React js?
Мой код:
КОНТЕКСТ:
authContext.js
import React from 'react'
const AuthContext = React.createContext()
export const AuthProvider = AuthContext.Provider
export const AuthConsumer = AuthContext.Consumer
export default AuthContext
ФУНКЦИОНАЛЬНЫЙ компонент:
App.js
...
import AuthPage from './pages/AuthPage';
import { AuthProvider } from './components/Context/authContext'
function App(props) {
const [isAuthenticated, setIsAuthenticated] = useState(false);
const checkAuthenticated = async () => {
//console.time('fetch')
try {
const res = await fetch("http://localhost:4000/api/verify", {
method: "POST",
headers: { jwt_token: localStorage.token }
});
const parseRes = await res.json();
parseRes === true ? setIsAuthenticated(true) : setIsAuthenticated(false);
} catch (err) {
console.error(err.message);
}
//console.timeEnd('fetch')
};
const setAuth = boolean => {
setIsAuthenticated(boolean);
};
useEffect(() => {
checkAuthenticated();
}, [isAuthenticated, setAuth]);
return (
<Fragment>
<BrowserRouter basename={'/'}>
<GAListener>
<Switch>
<LayoutRoute
exact
path="/login"
layout={EmptyLayout}
component={props => (
<AuthProvider value={{ setAuth: setAuth }}>
<AuthPage {...props} authState={STATE_LOGIN} />
</AuthProvider>
)}
/>
<Redirect to="/" />
</Switch>
</GAListener>
</BrowserRouter>
</Fragment>
)
}
export default App;
Компонент КЛАСС:
AuthForm.js
import AuthContext from '../components/Context/authContext'
class AuthForm extends React.Component {
constructor(props) {
super(props);
this.state = {
usernameInput: '',
emailInput: '',
passwordInput: '',
confirmPasswordInput: '',
remeberMe: false,
agreeTerms: false,
toDashboard: false
};
}
componentDidMount() {
if (localStorage.token) {
this.setState(() => (
{
toDashboard: true
}
))
}
}
componentDidUpdate() {
**// I WANT TO ACCESS THE 'setAuth' function here**
}
render() {
return (
<div>
//Some code
</div>
);
}
}
export default AuthForm;
Используя функцию setAuth из AuthForm.js (компонент класса), я хочу изменить значение isAuthenticated в App.js (функциональный компонент). Итак, в основном я хочу получить доступ к setAuth в componentDidUpdate().
2 ответа
Решение
Решил проблему с помощью @gemhar
Изменения, которые необходимо внести в AuthForm.js
...
import AuthContext from '../components/Context/authContext'
class AuthForm extends React.Component {
//Add this line
static contextType = AuthContext;
constructor(props) {
super(props);
this.state = {
usernameInput: '',
emailInput: '',
passwordInput: '',
confirmPasswordInput: '',
remeberMe: false,
agreeTerms: false,
toDashboard: false
};
}
componentDidMount() {
if (localStorage.token) {
this.setState(() => (
{
toDashboard: true
}
))
}
}
componentDidUpdate() {
//I can access setAuth here
this.context.setAuth(true)
//or by destructuring
let {setAuth} = this.context;
setAuth(true)
}
render() {
return (
<div>
//Some code
</div>
);
}
}
export default AuthForm;
Наиболее распространенный способ доступа к Context из компонента класса - через статический contextType. Если вам нужно значение из контекста вне рендеринга или в методе жизненного цикла, вы можете использовать его таким образом.
import React from "react";
import AuthContext from "./context";
class AuthForm extends React.Component {
constructor(props) {
...
}
static contextType = AuthContext
componentDidUpdate() {
const {setAuth} = this.context
// Access the 'setAuth' function here
}
render() {
return <div>Some code</div>;
}
}
export default AuthForm;