I make mistakes in Next js, but I dont know where - github

I use Next js dont correct, but I dont understend why. I saw github repository other programers, but I dont see where I made mistakes. That I make mistakes tolt me employer. The only one differences I found is I use only globals.css, but I think it dont mitakes. I want to grow as a programer, but I cant become better whisout your help. Please told me where i make mistakes in Next js.
My github repository: https://github.com/Yury11111111111/books-catalog
Code:
componets/BookComponent.js
import React from "react";
import Link from "next/link"
import Image from 'react-bootstrap/Image'
const BookComponent = (props) => {
return (
<>
<Link href={`/book/${props.book.id}`}>
<div className="book__wraper">
{props.book?.volumeInfo?.categories ?
<div className="book__category">{props.book?.volumeInfo?.categories[0]}</div>
: <></>}
{props.book?.volumeInfo?.imageLinks?.thumbnail ? (
<Image
src={props.book?.volumeInfo?.imageLinks?.thumbnail}
alt="book cover"
className="book__img"
/>
) : (
<Image className="noCover" src="https://rublevbar.com/files/rublevbar/image/no_product.jpg" alt="no book cover" />
)}
<div className="book__title">{props.book?.volumeInfo?.title}</div>
<div className="book__autors">{props.book?.volumeInfo?.authors}</div>
</div></Link>
</>
);
};
export default BookComponent;
pages/_app.js
import "../styles/globals.css";
import { store } from "../store";
import { Provider } from "react-redux";
import 'bootstrap/dist/css/bootstrap.min.css';
function MyApp({ Component, pageProps }) {
return (
<Provider store={store}>
<Component {...pageProps} />
</Provider>
);
}
export default MyApp;
pages/index.js
import React, { useEffect, useState } from "react";
import { useSelector, useDispatch } from "react-redux";
import { fetchBooksData } from "../slices/booksSlice";
import Head from "next/head";
import { Container, Form, Row, Col, Button, InputGroup } from "react-bootstrap";
import BookComponent from "../componets/BookComponent";
export default function Home() {
const books = useSelector((state) => state.books.books);
const name = useSelector((state) => state.books.name);
const startIndex = useSelector((state) => state.books.startIndex);
const error = useSelector((state) => state.books.error);
const [resultName, setResultName] = useState("book");
const [resultStartIndex, setResultStartIndex] = useState(0);
const [resultCategory, setResultCategory] = useState("all");
const [resultSort, setResultSort] = useState("relevance");
const dispatch = useDispatch();
useEffect(() => {
dispatch(
fetchBooksData({
name: resultName,
startIndex: resultStartIndex,
category: resultCategory,
sort: resultSort,
})
);
}, [resultName, resultStartIndex, resultCategory, resultSort, dispatch]);
if (error === "error") {
dispatch(
fetchBooksData({
name: resultName,
startIndex: resultStartIndex,
category: resultCategory,
sort: resultSort,
})
);
}
function categoryChange() {
setResultCategory(document.querySelector("#category").value);
setResultStartIndex(0);
dispatch(
fetchBooksData({
name: resultName,
startIndex: resultStartIndex,
category: resultCategory,
sort: resultSort,
})
);
}
function sortChange() {
setResultSort(document.querySelector("#sort").value);
setResultStartIndex(0);
dispatch(
fetchBooksData({
name: resultName,
startIndex: resultStartIndex,
category: resultCategory,
sort: resultSort,
})
);
}
function handleSubmit() {
const input = document.querySelector("#form");
setResultName(input.value);
}
function go_back() {
setResultStartIndex(resultStartIndex - 30);
}
function go_forward() {
setResultStartIndex(resultStartIndex + 30);
}
function handleKeyPress(e) {
if (e.charCode == 13) {
e.preventDefault()
const input = document.querySelector("#form");
setResultName(input.value);
}
}
return (
<>
<Head>
<title>Books catalog</title>
</Head>
<div id="page-preloader" className="preloader">
<div className="loader"></div>
</div>
<header className="header">
<Container>
<h1 className="title">Search for books</h1>
<Form>
<Row className="justify-content-center">
<Col xl={6}>
<InputGroup>
<Form.Control
onKeyPress={handleKeyPress}
id="form"
placeholder="Search books"
/>
<Button type="button" onClick={handleSubmit}>
Search
</Button>
</InputGroup>
</Col>
</Row>
<Row className="mt-3 justify-content-center">
<Col xl={3}>
<Form.Select
onChange={categoryChange}
id="category"
aria-label="Default select example"
>
<option value="all">all</option>
<option value="art">art</option>
<option value="biography">biography</option>
<option value="computers">computers</option>
<option value="history">history</option>
<option value="medical">medical</option>
<option value="poetry">poetry</option>
</Form.Select>
</Col>
<Col xl={3}>
<Form.Select
onChange={sortChange}
id="sort"
aria-label="Default select example"
>
<option value="relevance ">relevance </option>
<option value="newest">newest</option>
</Form.Select>
</Col>
</Row>
</Form>
</Container>
</header>
<Container>Всего книг по вашему запросу: {books.totalItems}</Container>
<Container>
<div className="books">
{books.items?.map((book, index) => {
return <BookComponent book={book} key={index} />;
})}
</div>
</Container>
<footer>
{resultStartIndex !== 0 ? (
<Button className="go_back" onClick={go_back}>
go back
</Button>
) : (
<></>
)}
{books.totalItems > resultStartIndex ? (
<Button className="go_forward" onClick={go_forward}>
go forward
</Button>
) : (
<></>
)}
</footer>
</>
);
}
pages/book/[id].js
import React, { useState, useEffect } from "react";
import Link from "next/link";
import { Button, Container, Image, Row, Col } from "react-bootstrap";
import { useSelector, useDispatch } from "react-redux";
import { fetchThisBookData } from "../../slices/thisBookSlice";
import { useRouter } from "next/router";
export default function bookId() {
const router = useRouter();
const book = useSelector((state) => state.thisBook.thisBook);
const error = useSelector((state) => state.thisBook.error);
const dispatch = useDispatch();
useEffect(() => {
dispatch(
fetchThisBookData({
id: router.query.id,
})
);
}, [dispatch, router]);
if (error === "error") {
dispatch(
fetchThisBookData({
id: router.query.id,
})
);
}
console.log(book);
return (
<div>
<Container>
<div id="page-preloader" className="preloader">
<div className="loader"></div>
</div>
<Link href={"/"} className="back">
<Button className="back">Back</Button>
</Link>
<Row className="justify-content-center">
<Col>
<h1 className="this_book__title">{book?.volumeInfo?.title}</h1>
</Col>
</Row>
<Row>
<Col xl={6}>
<strong>Категории:</strong>
{book?.volumeInfo?.categories ? (
<div className="this_book__category">
{book?.volumeInfo?.categories}
</div>
) : (
<div>Нет категорий</div>
)}
<div className="this_book__autors">
<strong>
{book?.volumeInfo?.authors.length === 1 ? (
<>Автор </>
) : (
<>Авторы: </>
)}
</strong>
{book?.volumeInfo?.authors}
</div>
<br />
</Col>
<Col xl={6}>
{book?.volumeInfo?.imageLinks?.extraLarge ? (
<Image
src={book?.volumeInfo?.imageLinks?.extraLarge}
alt="book cover"
className="this_book__img"
/>
) : (
<Image
className="noCover"
src="https://rublevbar.com/files/rublevbar/image/no_product.jpg"
alt="no book cover"
/>
)}
</Col>
</Row>
</Container>
</div>
);
}
slices/booksSlice.js
import { createSlice, createAsyncThunk } from "#reduxjs/toolkit";
const initialState = {
books: [],
status: null,
error: null,
};
export const fetchBooksData = createAsyncThunk(
"books/fetchData",
async function (state) {
const response = await fetch(
`https://www.googleapis.com/books/v1/volumes?q=${state.name}+${state.category}&startIndex=${state.startIndex}&maxResults=30&orderBy=${state.sort}`
);
const data = await response.json();
return data;
}
);
export const booksSlice = createSlice({
name: "books",
initialState,
extraReducers: {
[fetchBooksData.pending]: (state) => {
state.status = "loading";
state.error = null;
const preloader = document.querySelector("#page-preloader");
if (preloader.classList.contains("done")) {
preloader.classList.remove("done");
}
},
[fetchBooksData.fulfilled]: (state, action) => {
state.status = "resolved";
state.error = null;
state.books = action.payload;
const preloader = document.querySelector("#page-preloader");
if (!preloader.classList.contains("done")) {
preloader.classList.add("done");
}
},
[fetchBooksData.rejected]: (state) => {
state.error = "error";
console.log("Error");
},
},
});
export default booksSlice.reducer;
slices/thisBookSlice.js
import { createSlice, createAsyncThunk } from "#reduxjs/toolkit";
const initialState = {
thisBook: [],
status: null,
error: null,
};
export const fetchThisBookData = createAsyncThunk(
"books/fetchThisData",
async function (state) {
const response = await fetch(
`https://www.googleapis.com/books/v1/volumes/${state.id}`
);
const data = await response.json();
return data;
}
);
export const thisBookSlice = createSlice({
name: "book",
initialState,
extraReducers: {
[fetchThisBookData.pending]: (state) => {
state.status = "loading";
state.error = null;
const preloader = document.querySelector("#page-preloader");
if (preloader.classList.contains("done")) {
preloader.classList.remove("done");
}
},
[fetchThisBookData.fulfilled]: (state, action) => {
state.status = "resolved";
state.error = null;
state.thisBook = action.payload;
const preloader = document.querySelector("#page-preloader");
if (!preloader.classList.contains("done")) {
preloader.classList.add("done");
}
},
[fetchThisBookData.rejected]: (state) => {
state.error = "error";
console.log("Error");
},
},
});
export default thisBookSlice.reducer;

Related

how to integrate tailwind into formik forms

I am trying to implement tailwindcss styles into Formik to style forms. But the styles declared through className are not being applied?
I think Formik is using classname to define input type and tailwind uses the same method to declare styles?
my form page:
import React from "react";
import * as yup from "yup"
import { Formik, Form } from 'formik'
import { MyTextInput } from "../components/FormParts";
let mainFormSchema = yup.object().shape({
name: yup.string().trim().required()
})
const tryMainForm = () => {
const initValues = {
name: ''
}
return (
<div>
<h1>Any place in your app!</h1>
<Formik
initialValues={initValues}
validationSchema={mainFormSchema}
onSubmit={(values, { setSubmitting }) => {
setTimeout(() => {
alert(JSON.stringify(values, null, 2));
setSubmitting(false);
}, 400);
}}
>
{({ isSubmitting }) => (
<Form>
<MyTextInput
label="name"
name="name"
type="text"
placeholder="name"
/>
<button type="submit" disabled={isSubmitting}>
Submit
</button>
</Form>
)}
</Formik>
</div>
)
}
export default tryMainForm
formpart component:
import { useField } from "formik";
export const MyTextInput = ({ label, ...props }) => {
const [field, meta] = useField(props)
return (
<>
<label htmlFor={props.id || props.name} className="block text-sm font-medium text-gray-700">{label}</label>
<input className="shadow-sm focus:ring-indigo-500 focus:border-indigo-500 block w-full sm:text-sm border-gray-300 rounded-md" {...field} {...props} />
{meta.touched && meta.error ? (
<div className="error">{meta.error}</div>
) : null}
</>
)
}
can you suggest a way to deal with this?
tailwind applies styles properly to label but doesn't with input?

Redirecting/Rendering different component upon validation ionic react

I'm fairly new Ionic React and trying to create an App using Ionic framework. I have a use case where I would like to redirect to another page upon a button press and validation from a function.
Here is the component I am working with
import React, { useState } from 'react';
import {
IonContent,
IonHeader,
IonPage,
IonTitle,
IonToolbar,
IonInput,
IonButton,
IonRow,
IonCol,
useIonViewWillEnter,
useIonViewWillLeave,
IonLabel
} from '#ionic/react';
import './LogIn.css'
import MainMenu from "../MainMenu";
const LogIn: React.FC<{register?: boolean; onClose?: any}> = () => {
const [email, setEmail] = useState<string>();
const [password, setPassword] = useState<string>();
function handleLoginButtonPress() {
if (validateEmail() && password !== undefined && password.trim() !== "") {
// Network call here to check if a valid user
console.log("valid email")
return <MainMenu/>
}
}
function validateEmail () {
if (email !== undefined && email.trim() !== "") {
const regexp = /^(([^<>()[\]\\.,;:\s#"]+(\.[^<>()[\]\\.,;:\s#"]+)*)|(".+"))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return regexp.test(email);
}
return false;
}
useIonViewWillEnter(() => {
console.log("Entering LogIn");
});
useIonViewWillLeave(() => {
console.log("Exiting LogIn");
});
return (
<IonPage id="loginIonPage">
<IonHeader>
<IonToolbar color="primary" mode="md">
<IonTitle class="ion-text-center">Login or Register</IonTitle>
</IonToolbar>
</IonHeader>
<IonContent id="loginPage">
<div id="loginDialog">
<form>
<IonLabel>Email</IonLabel>
<IonRow>
<IonCol id="userName">
<IonInput
name="email"
value={email}
onIonChange={e => setEmail(e.detail.value!)}
clearInput
type="email"
placeholder="Email"
class="input"
padding-horizontal
clear-input="true"
required/>
</IonCol>
</IonRow>
<IonLabel>Password</IonLabel>
<IonRow>
<IonCol id="password">
<IonInput
clearInput
name="password"
value={password}
onIonChange={e => setPassword(e.detail.value!)}
type="password"
placeholder="Password"
class="input"
padding-horizontal
clear-input="true"
required/>
</IonCol>
</IonRow>
</form>
</div>
<div id="buttons">
<IonButton
onClick={handleLoginButtonPress}
type="submit"
strong={true}
expand="full"
style={{ margin: 20 }}>
Log in
</IonButton>
<IonButton
routerLink="/registerUser"
type="submit"
strong={true}
expand="full"
style={{ margin: 20 }}>
Register
</IonButton>
</div>
</IonContent>
</IonPage>
);
};
export default LogIn;
How can I redirect to another page from the function handleLoginButtonPress which is invoked upon clicking on Login button. I tried reading through ionic doc but that did not help as it redirects whenever there is button click or click on an IonElement like IonLabel.
Use react-router-dom hooks
https://reacttraining.com/react-router/web/api/Hooks/usehistory
import { useHistory } from "react-router-dom";
const ExampleComponent: React.FC = () => {
const history = useHistory();
const handleLoginButtonPress = () => {
history.push("/main");
};
return <IonButton onClick={handleLoginButtonPress}>Log in</IonButton>;
};
export default ExampleComponent;
Thanks, #MUHAMMAD ILYAS and it would have worked for me. But I managed to leverage the react state as below, I have added as an answer as I could not format the code there,
const ValidateUser : React.FC = () => {
const [login, setLogin] = useState(false);
function isUserLoggedIn() {
return login;
}
return(
<IonReactRouter>
<IonRouterOutlet>
<Route path="/" render={() => isUserLoggedIn()
? <MainMenu/>
: <LogIn setUserLoggedIn={() => {setLogin(true)}}/>} exact={true}/>
</IonRouterOutlet>
</IonReactRouter>
);
};
const LogIn: React.FC<{setUserLoggedIn?: any}> = ({setUserLoggedIn}) => {
.
.
function onLoginButtonPress() {
setUserLoggedIn();
}
}
Thanks

react-semantic-ui-datepickers no form value in redux-form

This issue applied the standard implementation without additional customisations.
The is no value on submit of the form and onChange does not fire with the current value.
<Form onSubmit={handleSubmit(this.onSubmit)}>
<Form.Group>
<Field
component={SemanticDatepicker}
name="working"
dateFormat="DD/MM/YYYY"
label="Date of birth"
placeholder="select your DOB"
size="small"
onChange={(e, value) => {
console.log(e, value);
}}
/>
</Form.Group>
<Form.Field
control={Button}
color="purple"
className="submit-btn"
type="submit"
width={6}
>
Save
</Form.Field>
</Form>
A minimal version can be found here https://github.com/chrishj59/datepickerIssue
I could capture the onChange value by creating a custom component which wrapped the <SemanticDatepicker />. I also added mapStateToProps to log the redux-form values. You can consider this as a starting point and work on this.
//SongList.js
state = {
date: "",
};
render(){
const DatePick = () => {
return (
<SemanticDatepicker
onChange={this.datePickerOnChange}
format="YYYY-MM-DD"
/>
);
};
return (
<Form onSubmit={handleSubmit(this.onSubmit)}>
<Form.Group>
<Field
component={DatePick}
name="working"
dateFormat="DD/MM/YYYY"
label="Date of birth"
placeholder="select your DOB"
size="small"
/>
</Form.Group>
<Form.Field
control={Button}
color="purple"
className="submit-btn"
type="submit"
width={6}
>
Save
</Form.Field>
</Form>
);
}
//App.js
import { connect } from "react-redux";
const App = (props) => {
console.log(props.form);
return (
<div>
{" "}
<SongList />
</div>
);
};
const mapStateToProps = (state) => ({
form: state.form,
});
export default connect(mapStateToProps)(App);
I managed to resolve using semantic-ui-redux-form-fields to wrap the Semantic UI component. This now gives the correct format and value appearing in the validate function and formProps.
import React from "react";
imp ort { fieldEnhance } from "semantic-ui-redux-form-fields";
import { compose } from "redux";
import SemanticDatepicker from "react-semantic-ui-datepickers";
import "react-semantic-ui-datepickers/dist/react-semantic-ui-datepickers.css";
const DatePickerPure = (props) => {
const { currentValue, input, ...rest } = props;
const defaultProps = {
format: "DD/MMM/YYYY",
onChange: (event, data) => input.onChange(data.value),
value: currentValue,
...rest,
};
return <SemanticDatepicker {...props} {...defaultProps} />;
};
export default compose(fieldEnhance)(DatePickerPure);

How to pass state from checkboxes to a parent component?

I have a class (Cookbook) that passes a click handler "handleOnChange" to a child component (Filter). Filter renders checkboxes. On those checkboxes, I execute the handleOnChange. I want to update the state that exists in Cookbook, but even though handleOnChange is declared in Cookbook, it does not recognize this.state.selectedStaples. The error takes place in the handleOnChange function on the first non-console.log line. How do I update the state of selectedStaples in Cookbook?
Here is Cookbook
class Cookbook extends React.Component {
constructor(){
super();
this.state ={
cookbook: data,
selectedStaples: [],
}
}
getStapleList(recipes){
let stapleList = [];
recipes.forEach(function(recipe){
recipe.ingredient_list.forEach(function(list){
stapleList.push(list.needed_staple);
});
});
let flattenedStapleList = stapleList.reduce(function(a,b){
return a.concat(b);
})
return flattenedStapleList
}
handleOnChange(staple, isChecked, selectedStaples) {
console.log(staple);
console.log(isChecked);
console.log(selectedStaples);
const selectedStaples = this.state.selectedStaples;
// if (isChecked) {
// this.setState({
// selectedStaples: selectedStaples.push(staple)
// })
// } else {
// this.setState({
// selectedStaples: selectedStaples.filter(selectedStaple => selectedStaple !== staple)
// })
// }
}
render(){
const selectedStaples = this.state.selectedState;
const cookbook = this.state.cookbook;
const stapleList = this.getStapleList(cookbook.recipes);
return(
<div className="cookbook">
<div className="filter-section">
<h1>This is the filter section</h1>
<Filter stapleList = {stapleList} onChange={this.handleOnChange}/>
</div>
<div className="recipes">
<h1>This is where the recipes go</h1>
<div className="recipe">
<Recipe cookbook = {cookbook}/>
</div>
</div>
</div>
);
}
}
and Filter
class Filter extends React.Component {
render(){
const stapleList = this.props.stapleList;
const checkboxItems = stapleList.map((staple, index) =>
<div key = {index}>
<label>
<input
type="checkbox"
value="{staple}"
onClick={e => this.props.onChange(staple, e.target.checked)}
/>
{staple}
</label>
</div>
);
return (
<form>
{checkboxItems}
</form>
);
}
}

How to manage checkbox filtering with React?

I am working on my first React app. It is a recipe sort of app. It has an ingredients filter. The main component is the Cookbook component. It has a Filter component and a Recipe component.
The Recipe component displays all recipes on load. The Filter component displays all needed ingredients or staples. This part all works great.
What I want to do now is when a person clicks on a staple, lets say butter, it would then filter the entire recipe list. My assumption is that I need to pass the state of Filter up. How can I do this with these checkboxes?
Here is what I have:
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
var data = require('./recipes.json');
function IngredientDetailList(props){
const ingredientList = props.ingredientList;
const listItems = ingredientList.map((ingredient, index) =>
<div key={index}>
{ingredient.measurement_amount}
{ingredient.measurement_unit}
{ingredient.ingredient}
</div>
);
return (
<div>{listItems}</div>
)
}
function Recipe(props){
const recipeList = props.cookbook.recipes
const listItems = recipeList.map((recipe) =>
<div key={recipe.id}>
<h2>{recipe.name}</h2>
<IngredientDetailList ingredientList = {recipe.ingredient_list}/>
</div>
);
return(
<div>{listItems}</div>
)
}
class Filter extends React.Component {
constructor(){
super();
this.state = {
checkedStaples: {},
}
}
render(){
const stapleList = this.props.stapleList;
const checkboxItems = stapleList.map((staple, index) =>
<div key = {index}>
<label>
<input type="checkbox" value="{staple}"/>
{staple}
</label>
</div>
);
return (
<form>
{checkboxItems}
</form>
);
}
}
class Cookbook extends React.Component {
constructor(){
super();
this.state ={
cookbook: data
}
}
getStapleList(recipes){
let stapleList = [];
recipes.forEach(function(recipe){
recipe.ingredient_list.forEach(function(list){
stapleList.push(list.needed_staple);
});
});
let flattenedStapleList = stapleList.reduce(function(a,b){
return a.concat(b);
})
return flattenedStapleList
}
render(){
const cookbook = this.state.cookbook;
const stapleList = this.getStapleList(cookbook.recipes);
return(
<div className="cookbook">
<div className="filter-section">
<h1>This is the filter section</h1>
<Filter stapleList = {stapleList}/>
</div>
<div className="recipes">
<h1>This is where the recipes go</h1>
<div className="recipe">
<Recipe cookbook = {cookbook}/>
</div>
</div>
</div>
);
}
}
ReactDOM.render(
<Cookbook />,
document.getElementById('root')
);
You could try to do something like this:
// ....
function Recipe(props){
const selectedStaples = props.selectedStaples;
const recipeList = props.cookbook.recipes
const listItems = recipeList.map((recipe) => {
const hasStaple = ingredient_list.reduce(
(_hasStaple, staple) => _hasStaple || selectedStaples.includes(staple),
false
);
// only show recipe if it has a staple
if (selectedStaples.length === 0 || hasStaple)
return (
<div key={recipe.id}>
<h2>{recipe.name}</h2>
<IngredientDetailList ingredientList = {recipe.ingredient_list}/>
</div>
);
}
return null;
}
);
return(
<div>{listItems}</div>
)
}
class Filter extends React.Component {
constructor(){
super();
this.state = {
checkedStaples: {},
}
}
render(){
const stapleList = this.props.stapleList;
const checkboxItems = stapleList.map((staple, index) =>
<div key = {index}>
<label>
<input
type="checkbox"
value="{staple}"
onClick={e => this.props.onChange(staple, e.checked)}
/>
{staple}
</label>
</div>
);
return (
<form>
{checkboxItems}
</form>
);
}
}
class Cookbook extends React.Component {
constructor(){
super();
this.state ={
cookbook: data,
selectedStaples: []
}
}
getStapleList(recipes){
let stapleList = [];
recipes.forEach(function(recipe){
recipe.ingredient_list.forEach(function(list){
stapleList.push(list.needed_staple);
});
});
let flattenedStapleList = stapleList.reduce(function(a,b){
return a.concat(b);
})
return flattenedStapleList
}
handleOnChange(staple, isChecked) {
const selectedStaples = this.state.selectedStaples;
if (isChecked) {
this.setState({
selectedStaples: selectedStaples.push(staple);
})
} else {
this.setState({
selectedStaples: selectedStaples.filter(selectedStaple => selectedStaple !== staple);
})
}
}
render(){
const selectedStaples = this.state.selectedStaples;
const cookbook = this.state.cookbook;
const stapleList = this.getStapleList(cookbook.recipes);
return(
<div className="cookbook">
<div className="filter-section">
<h1>This is the filter section</h1>
<Filter stapleList = {stapleList} onChange={this.handleOnChange.bind(this)}/>
</div>
<div className="recipes">
<h1>This is where the recipes go</h1>
<div className="recipe">
<Recipe cookbook = {cookbook} selectedStaples={selectedStaples} />
</div>
</div>
</div>
);
}
}
ReactDOM.render(
<Cookbook />,
document.getElementById('root')
);
It keeps track of the selected stapes in the cookbook component and passes that on to recipe