Here is a React component that can hold state and share context (within the component, in a “React Island.“)
Your logged in status: false
You need to click to log in.
Here is the code for this page:
//src/pages/auth-context.astro
---
import BaseLayout from '../../layouts/BaseLayout';
import AuthApp from '../../components/AuthApp.jsx';
import { Markdown } from 'astro/components';
---
<BaseLayout title="Auth State Context">
<main>
<Markdown>
Here is a React component that can hold state (within the component, in a "React Island.")
</Markdown>
<hr />
<AuthApp client:load />
<hr />
<Markdown>
Here is the code for this page:
</Markdown>
</main>
</BaseLayout >
And this is the AuthApp.jsx component that’s being rendered.
//src/components/AuthApp.jsx
import React, { useState } from 'react';
import LogInButton from '../components/LoginButton.jsx';
import LogOutButton from '../components/LogoutButton.jsx';
import AuthContext from '../components/AuthContext.jsx';
const AuthApp = () => {
const [auth, setAuth] = useState(false);
const login = () => {
setAuth(true);
};
const logout = () => {
setAuth(false);
};
return (
<>
<p>Your logged in status: {auth} </p>
<AuthContext.Provider value={{ auth: auth, login: login, logout: logout }}>
<p>{auth ? 'Yay! You are logged in.' : 'You need to click to log in.'}</p>
<LogInButton />
<LogOutButton />
</AuthContext.Provider>
</>
);
};
export default AuthApp;
With this context…
// src/components/AuthContext.jsx
import React, { createContext } from 'react';
const AuthContext = createContext({
auth: null,
login: () => {}, //For the sake of playing with context, I'm holding these functions in context, too. Normally, I wouldn't bother.
logout: () => {},
});
export default AuthContext;
and some external button components that also accept their functions through context.
//Login Button at src/components/LoginButton.jsx
import React, { useContext } from 'react';
import AuthContext from '../components/AuthContext.jsx';
const LoginButton = () => {
const auth = useContext(AuthContext);
return (
<> //NB: gratuitous fragment, really only necessary if returning more than one element
<button onClick={auth.login}>Login</button>
</>
);
};
export default LoginButton;
//Logout Button at src/components/LogoutButton.jsx
import React, { useContext } from 'react';
import AuthContext from '../components/AuthContext.jsx';
const LogoutButton = () => {
const auth = useContext(AuthContext);
return (
<>
<button onClick={auth.logout}>Click To Logout</button>
</>
);
};
export default LogoutButton;