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;