Here is a list of books generated by components sharing context. (It’s a hydrated component, so try clicking the buttons!)
NOTE: This is how to execute context, but it’s clearly not the best example of when or why to use context! It’s just an implementation of the hook, for the sake of testing out the pattern. Super-long blog post in excrutiating detail re: how to do this is available at “React Context Post”
- The Road to React - 19.99 $
- The Road to GraphQL - 29.99 $
- The Road to GastbyJS - 29.99 $
- The Rocket to Astro! - 29.99 $
This is the code for this page (so far!):
//src/pages/experiments/react-context.astro
---
import BaseLayout from '../../layouts/BaseLayout';
import CurrencyApp from '../../components/CurrencyApp.jsx';
import { Markdown } from 'astro/components';
---
<BaseLayout title="React currency context">
<Markdown>
Here is a list of books generated by React components sharing context:
</Markdown>
<hr />
<CurrencyApp client:load/>
<hr />
<Markdown>
This is the code for this page:
</Markdown>
</BaseLayout>
Here are the app components:
//Create the file src/components/CurrencyContext.jsx
import { createContext } from 'react';
const CurrencyContext = createContext();
export default CurrencyContext
// src/components/CurrencyApp.jsx
import React from 'react';
import CurrencyContext from '../components/CurrencyContext.jsx';
import Books from "../components/Books.jsx";
//One big object, whose properties are a list, a function, and a currency symbol
const DATA = {
list: [
{
id: '1',
title: 'The Road to React',
price: 19.99,
},
{
id: '2',
title: 'The Road to GraphQL',
price: 29.99,
},
{
id: '3',
title: 'The Road to GastbyJS',
price: 29.99,
},
{
id: '4',
title: 'The Rocket to Astro!',
//title: 'The Voyage to Astro!',
price: 29.99,
},
],
buy: () => {
alert("Sorry, this is just a test!");
},
currency: "$",
};
const CurrencyApp = () => {
return (
<CurrencyContext.Provider value={DATA} > //Sharing the entire object via context
<Books />
</CurrencyContext.Provider>
);
};
export default CurrencyApp;
// src/components/Books.jsx
import React, { useContext } from 'react';
import CurrencyContext from '../components/CurrencyContext.jsx';
import Book from '../components/Book';
const Books = () => {
const { list } = useContext(CurrencyContext) // destructure just the list array
return (
<ul>
{list.map((item) => (
<Book key={item.id} item={item} />
))}
</ul>
);
};
export default Books
// src/components/Book.jsx
import React, { useContext } from 'react';
import CurrencyContext from '../components/CurrencyContext.jsx';
import BookBuyButton from '../components/BookBuyButton.jsx';
const Book = ({ item }) => {
const { currency } = useContext(CurrencyContext); //destructure just the currency symbol
return (
<li style={{lineHeight: "1.85em"}}>
<BookBuyButton /> {item.title} - {item.price} {currency}
</li>
);
};
export default Book
And now, a new component, a Buy button, that will execute our buy function when clicked. (JavaScript! Yay!) This is the component that will require us to hydrate our CurrencyApp on the Astro page.
// src/componenst/BuyBookButton.jsx
import React, { useContext } from "react";
import CurrencyContext from "../components/CurrencyContext.jsx";
const BookBuyButton = () => {
const { buy } = useContext(CurrencyContext); //destructure just the buy function
return (
<button onClick={buy}>Buy!</button>
);
};
export default BookBuyButton;