useEffect is not invoking more then once based on the dependency - javascript

I am making an expense tracker. I am trying to change the "total" amount everytime "totalIncome" and "totalExpense" is passed to the useEffect as dependency from the props. But the useEffect invoke only once.
const Main = ({ getData, totalIncome, totalExpense }) => {
const [total, setTotal] = useState(parseInt(0))
const [type, setType] = useState('income')
const [date, setDate] = useState('')
const [amount, setAmount] = useState('')
const [category, setCategory] = useState('Rent')
const [income, setIncome] = useState('')
const [id, setId] = useState(Date.now())
const changeType = (e) =>{
setType(e.target.value)
}
const handleDate = (e) =>{
setDate(e.target.value)
}
const handleAmount = (e) =>{
setAmount(parseInt(e.target.value))
}
const handleCategory = (e) =>{
setCategory(e.target.value)
}
const handleIncome = (e) =>{
setIncome(e.target.value)
}
const handleSubmit = (e) =>{
e.preventDefault()
setId(Date.now())
getData({total, type, date, amount, category , income, id})
type === 'income' ? setTotal(parseInt(total + amount)) : setTotal(parseInt(total - amount))
setAmount('')
setIncome('')
setDate('')
}
useEffect(()=>{
if(!category){
setCategory('Rent')
}
}, [category])
useEffect(() => {
setTotal(prev => prev + totalExpense)
}, [totalExpense]);
useEffect(() => {
setTotal(prev => prev - totalIncome)
}, [totalIncome]);
return (
<div className={main.container}>
<h1 className={main.headline}>Expense Tracker</h1>
<h2>{total >= 0 ? Total Balance: ${total} : Your debt: ${total}}</h2>
<hr style={{margin: '20px 0'}}/>
<form className={main.form} onSubmit={handleSubmit}>
<div className={main.typeBox}>
<div>
<label htmlFor='type'>Type:</label>
<select id='type' name='type' value={type} onChange={changeType} >
<option value="expense">Expense</option>
<option value="income">Income</option>
</select>
</div>
<div>
{type === 'income' && (
<div>
<label>Income:</label>
<input type='text' value={income} onChange={handleIncome}/>
</div>
)}
{type === 'expense' && (
<div>
<label htmlFor='category'>Category:</label>
<select onChange={handleCategory}>
<option value='Rent'>Rent</option>
<option value='Food'>Food</option>
<option value='Transport'>Transport</option>
<option value='Health'>Health</option>
<option value='Utility'>Utility</option>
<option value='Other'>Other</option>
</select>
</div>
)}
</div>
</div>
{ /*
Amount and date section
*/}
<div className={main.amountDate}>
<div>
<label>Amount:</label>
<input type="number" value={amount} onChange={handleAmount} required/>
</div>
<div>
<label>Date:</label>
<input type="date" value={date} onChange={handleDate} required/>
</div>
</div>
<button type='submit' className={main.create}>CREATE</button>
</form>
</div>
)
}
export default Main
How can i get the "total" amount change everytime the useEffect gets an update in the dependency ?

The useEffect hook only runs when the dependency array changes. If the dependency array contains numbers, then the number has to change for the hook to re-run. It will not re-run if the same numbers are passed in the following update.
Moreover, using the useEffect hook to change state based on props passed to it leads to very fragile components. I suggest that you calculate the total outside of this component and pass it into this component only for displaying. Alternatively, you can change total into a normal variable which will be recalculated on every render.
const Main = ({ getData, totalIncome, totalExpense }) => {
...
const total = totalIncome - totalExpense;
...
}

Related

React review form not submitting review on submit

I just want to preface this that I am learning JavaScript and React so this is all very new to me.
I am building a "simple" movie rating app and need to be able to push a review to a div "on submit" and cannot figure out how to do so. I have tried using update state in react and/or creating functions to try to accomplish this and cannot figure out how to do this for the life of me. I did somewhat succeed using the latter method, but was getting errors about using unique key props. The other problem was I am to use a star-rating component and when I submitted the review, it wasn't pushing that to the div. This is where I'm at currently:
import { Button, Form, Input } from "reactstrap";
import Stars from "./stars";
export default function ReviewForm() {
const [reviews, setReviews] = useState("");
const onChange = (e: any) => {
setReviews(e.target.value);
};
const onSubmit = (e: any) => {
console.log("Form Submitted");
};
return (
<div className="form-container">
<Stars />
<Form onSubmit={onSubmit}>
<Input
className="form-control" type="text"
placeholder="Enter you review"
value={reviews}
onChange={onChange}
/>
<br></br>
<Button type="submit" className="btn btn-primary">
Submit
</Button>
</Form>
</div>
);
}
// This is what I have in my Stars component:
import React, { useState } from "react";
import { FaStar} from 'react-icons/fa'
const Stars = () => {
const [rating, setRating] = useState(0);
const [hover, setHover] = useState(null);
return(
<div>
{[...Array(5)].map((star, i) => {
const ratingValue = i + 1;
return <label>
<input
type="radio"
name="rating"
value={ratingValue}
onClick={() => setRating(ratingValue)}
/>
<FaStar
className="star"
color={ratingValue <= (hover || rating) ? "gold" : "lightgray"}
size={20}
onMouseEnter={() => setHover(ratingValue)}
onMouseLeave={() => setHover(null)}
/>
</label>;
})}
<p>I rate this movie {rating + " stars"}</p>
</div>
);
};
export default Stars```
Here is the working version of your code. You should use key in your map and e.preventDefault() in your form submit function. As final touch you should set another state inside your form submit and show this value in a div or some html element. Also I see that you want to get child state into parent so you can call callback for this https://codesandbox.io/embed/brave-euler-ybp9cx?fontsize=14&hidenavigation=1&theme=dark
ReviewForm.js
export default function ReviewForm() {
const [reviews, setReviews] = useState("");
const [value, setValue] = useState("");
const [star, setStar] = useState();
const onChange = (e: any) => {
setReviews(e.target.value);
};
const onSubmit = (e: any) => {
e.preventDefault();
setValue(reviews + " with " + star + " star ");
};
return (
<div className="form-container">
<Stars setStar={setStar} />
<Form onSubmit={onSubmit}>
<Input
className="form-control"
type="text"
placeholder="Enter you review"
value={reviews}
onChange={onChange}
/>
<br></br>
<Button type="submit" className="btn btn-primary">
Submit
</Button>
<div>{value}</div>
</Form>
</div>
);
}
Stars.js
const Stars = ({ setStar }) => {
const [rating, setRating] = useState(0);
const [hover, setHover] = useState(null);
const handleClick = (ratingValue) => {
setRating(ratingValue);
setStar(ratingValue);
};
return (
<div>
{[...Array(5)].map((star, i) => {
const ratingValue = i + 1;
return (
<label key={i}>
<input
type="radio"
name="rating"
value={ratingValue}
onClick={() => handleClick(ratingValue)}
/>
<FaStar
className="star"
color={ratingValue <= (hover || rating) ? "gold" : "lightgray"}
size={20}
onMouseEnter={() => setHover(ratingValue)}
onMouseLeave={() => setHover(null)}
/>
</label>
);
})}
<p>I rate this movie {rating + " stars"}</p>
</div>
);
};
export default Stars;
You probably are seeing a page refresh when you press the submit button. This is the default behavior of HTML forms.
When using React or any front-end framework, you'd want to handle the form submission yourself rather than letting the browser submit your forms.
In your onSubmit function, add the following line
e.preventDefult()
const onSubmit = (e: any) => {
e.preventDefault()
console.log("Form Submitted");
};
Your code will work perfectly.
import { Button, Form, Input } from "reactstrap";
import Stars from "./stars";
export default function ReviewForm() {
const [Reviews, setReviews] = useState("");
const [ReviewsRating, setReviewsRating] = useState(5);
const [Reviews_, setReviews_] = useState([]);
const onChange = (e: any) => {
setReviews(e.target.value);
};
const onSubmit = (e: any) => {
e.preventDefault()
console.log("Form Submitted");
//After upload to the server
setReviews_([Reviews, ...Reviews_]
};
return (
<div className="form-container">
<Stars getRating={getRating}/>
<Form onSubmit={onSubmit}>
<Input
className="form-control" type="text"
placeholder="Enter you review"
value={reviews}
onChange={onChange}
/>
<br></br>
<Button type="submit" className="btn btn-primary">
Submit
</Button>
</Form>
<div class="reviews">
{Reviews_.map(item => <div> {item}</div> )}
</>
</div>
);
}```
Then to get the stars rating value use props like...
And make sure you call that property (function) inside your Starts component
const getRating =(value)=>{
setReviewsRating(value)
}

How to put values from json into inputs by default?

In my React component
import React, { useEffect, useState } from "react";
import { useParams } from "react-router";
import { NavLink } from "react-router-dom";
import "./styles/editIntern.sass";
const EditIntern = () => {
const { id } = useParams();
const [intern, setIntern] = useState([]);
const [name, inputName] = useState("");
const [email, inputEmail] = useState("");
const [start, inputStart] = useState("");
const [end, inputEnd] = useState("");
const [errorNameEmpty, isErrorNameEmpty] = useState(false);
const [errorEmailValid, iserrorEmailValid] = useState(false);
const [errorStartEmpty, isErrorStartEmpty] = useState(false);
const [errorEndEmpty, isErrorEndEmpty] = useState(false);
const validEmail = new RegExp(
/(\w+([-+.']\w+)*#\w+([-.]\w+)*\.\w+([-.]\w+)*)/gm
);
const onFormSubmit = (e) => {
e.preventDefault();
let startDate = new Date(start).getTime();
let endDate = new Date(end).getTime();
if (startDate > endDate) {
console.log("Start > end");
console.log(startDate);
console.log(endDate);
} else {
console.log("Ok");
console.log(startDate);
console.log(endDate);
}
};
useEffect(() => {
const fetchIntern = async () => {
const response = await fetch(`http://localhost:3001/interns/${id}`);
const intern = await response.json();
setIntern(intern);
};
fetchIntern();
console.log(`I want to get intern with id: ${id}!`);
}, [id]);
return (
<div className="container">
<img className="Logo" src="../logo.svg" alt="logo" />
<section className="EditIntern">
<NavLink to="/">
<button className="EditIntern_back">
<img
className="EditIntern_back-img"
src="../button_back_icon.svg"
alt="button_back"
/>{" "}
Back to list
</button>
</NavLink>
<form className="EditIntern_form">
<h4 className="EditIntern_form-title">Edit</h4>
<label className="EditIntern_form-label EditIntern_form-label_name">
Full name *
</label>
<input
className="EditIntern_form-input EditIntern_form-input_name"
type="text"
name="name"
value={name}
onChange={(e) => {
if (e.target.value === "") {
isErrorNameEmpty(true);
} else {
isErrorNameEmpty(false);
}
inputName(e.target.value);
}}
/>
{errorNameEmpty ? (
<span className="EditIntern_form-error EditIntern_form-error_name">
Name can't be empty
</span>
) : (
<></>
)}
<label className="EditIntern_form-label EditIntern_form-label_email">
Email address *
</label>
<input
className="EditIntern_form-input EditIntern_form-input_email"
type="text"
name="email"
value={email}
onChange={(e) => {
if (e.target.value === "") {
iserrorEmailValid(true);
} else if (!validEmail.test(e.target.value)) {
iserrorEmailValid(true);
} else {
iserrorEmailValid(false);
}
inputEmail(e.target.value);
}}
/>
{errorEmailValid ? (
<span className="EditIntern_form-error EditIntern_form-error_email">
Example: email#gmail.com
</span>
) : (
<></>
)}
<label className="EditIntern_form-label EditIntern_form-label_start">
Internship start *
</label>
<input
className="EditIntern_form-input EditIntern_form-input_start"
type="date"
name="email"
value={start}
onChange={(e) => {
if (!isNaN(e.target.valueAsNumber))
inputStart(e.target.valueAsNumber);
if (e.target.value === "") {
isErrorStartEmpty(true);
} else {
isErrorStartEmpty(false);
}
}}
/>
{errorStartEmpty ? (
<span className="EditIntern_form-error EditIntern_form-error_start">
Start date can't be empty
</span>
) : (
<></>
)}
<label className="EditIntern_form-label EditIntern_form-label_end">
Internship end *
</label>
<input
className="EditIntern_form-input EditIntern_form-input_end"
type="date"
name="email"
value={end}
onChange={(e) => {
if (!isNaN(e.target.valueAsNumber))
inputEnd(e.target.valueAsNumber);
if (e.target.value === "") {
isErrorEndEmpty(true);
} else {
isErrorEndEmpty(false);
}
}}
/>
{errorEndEmpty ? (
<span className="EditIntern_form-error EditIntern_form-error_end">
End date can't be empty
</span>
) : (
<></>
)}
<input
className="EditIntern_form-submit"
type="submit"
value="Submit"
onClick={onFormSubmit}
/>
</form>
</section>
</div>
);
};
export default EditIntern;
I need inputs to be filled with values from the intern array when this component is called (intern.name, intern.email ...) Now with useState the inputs are empty by default. I need by default with data from intern but with the ability to erase and fill in as you like.
As I already wrote, intern is an array with data that is rendered when this component is opened, it has all the data that needs to be placed by default.
The problem if i see correctly is in that you don't getting data from array intern you just getting it from name, email, etc.
So on start set that values like intern.name to name etc.
after that you could save it inside array using
setIntern({name: name, ...intern})
and contiue with that using other parametrs

redux toolkit state resets

I am stuck setting a state in react redux tool kit. My objective is to set the state by capturing some information from a form.
Store
import { createSlice } from '#reduxjs/toolkit'
export const SourceSlice = createSlice({
name: 'source',
initialState: {
name : "" ,
description:"",
version:"" ,
contact :"" ,
id:"",
} ,
reducers: {
addSource: (state ,action) => {
state.name = action.payload.name
state.description = action.payload.description
state.version = action.payload.version
state.contact = action.payload.contact
state.id = action.payload.name + "-" + action.payload.version
} ,
},
})
// Action creators are generated for each case reducer function
export const { addSource ,addExtract} = SourceSlice.actions
export default SourceSlice.reducer
Form
import { useDispatch } from 'react-redux'
import {addSource } from '../../Store/SourceSlice'
import React, {useState} from 'react'
const Source = () => {
const dispatch = useDispatch("")
const [name, setName] = useState('');
const [description, setDescription] = useState('');
const [version, setVersion] = useState('');
const [contact, setContact] = useState('');
const saveSourceDetails = () => {
const payload =
{
name : name,
description : description,
version: version ,
contact: contact
}
dispatch(addSource(payload))
};
const onDataChange = (event) => {
event.preventDefault();
if( event.target.name === "name"){
setName(event.target.value)
}
if( event.target.name === "description"){
setDescription(event.target.value)
}
if( event.target.name === "version"){
setVersion(event.target.value)
}
if( event.target.name === "contactPerson"){
setContact(event.target.value)
}
}
return (
<div>
<form className="ui form" onSubmit={saveSourceDetails}>
<div className="field">
<div className="Three fields">
<div className="field">
<input
type="text"
name="name"
value={name}
placeholder="Source Name"
onChange={onDataChange}
/>
</div>
<div className="field">
<input
type="text"
name="description"
value={description}
placeholder="Source Description"
onChange={onDataChange}
/>
</div>
<div>
<select
name="version"
multiple=""
className="ui fluid dropdown"
onChange={onDataChange}
>
<option value=""></option>
<option value="v1">v1</option>
<option value="v2">v2</option>
<option value="v3">v3</option>
</select>
</div>
<div className="field">
<input
type="text"
name="contactPerson"
value={contact}
placeholder="Contact Person"
onChange={onDataChange}
/>
</div>
<button className="ui button" type="submit">
+
</button>
</div>
</div>
</form>
</div>
);
};
export default Source;
Every time when i hit the button , the data is captured, send to redux the state is set for a second and the then state is reset to initial state. I am struggling to find out what makes the tool to reset everything. Any leads would help me.
PS: I am new to javascript and react
This function is the culprit. When you send the form, this gets called. You are not preventing the default event, so the page reloads, and you lose your Redux store.
const saveSourceDetails = () => {
const payload = {
name: name,
description: description,
version: version,
contact: contact
};
dispatch(addSource(payload));
};
Here's the corrected version:
const saveSourceDetails = (e) => {
e.preventDefault();
const payload = {
name: name,
description: description,
version: version,
contact: contact
};
dispatch(addSource(payload));
};

how to create a filter to dynamically render fetched items

How do I create a filter to dynamically render fetched items from an API in to get more than one filter criteria. I'm new to React.
Below is My App.js file where I'm fetching from the API, setting it in the 'records' state. I'm importing the FilterRecords component here
const App = () => {
const [records, setRecords] = useState([])
const [loading, setLoading] = useState(false)
const [currentPage, setCurrentPage] = useState(1)
const [recordsPerPage] = useState(20)
useEffect(() => {
const fetchRecords = async () => {
setLoading(true)
const res = await fetch('http://api.enye.tech/v1/challenge/records')
const data = await res.json();
setRecords(data.records.profiles)
setLoading(false)
}
fetchRecords()
// eslint-disable-next-line
}, [])
// Get current records
const indexOfLastRecord = currentPage * recordsPerPage // should give the index of the last records
const indexOfFirstRecord = indexOfLastRecord - recordsPerPage // should give the index of the first records
// Get current records
const currentRecords = records.slice(indexOfFirstRecord, indexOfLastRecord) // Slices out the number of records per page
// change page
const paginate = (pageNumber) => setCurrentPage(pageNumber)
return (
<Fragment>
<SearchBar />
<div className='container'>
<h2>Patients Record Details</h2>
<RecordsFilter />
<Pagination recordsPerPage={recordsPerPage} totalRecords={records.length} paginate={paginate} />
{!loading ? <Records loading={loading} records={currentRecords} /> : <div></div>}
</div>
</Fragment>
);
}
And Below is my filterRecords component. Here, I've destructured the records, filtered through them to only search for Gender, and mapped it to display the typed outcome. I'm not sure if the onChange, onSubmit is properly implemented. When I type into the filter input, I get cannot read property filter of undefined.
I need help with how to make it work properly
import React, { useState } from 'react'
const RecordsFilter = ({ records }) => {
const [search, setSearch] = useState('')
const [loading, setLoading] = useState('')
const onChange = (e) => {
setSearch({ [e.target.name]: e.target.value })
}
const filteredRecord = records.filter((record) => {
return record.Gender.includes('Male', 'Female', 'Prefer to skip')
})
const renderFilter = (
<div className='card card-body'>
<ul>
{filteredRecord.map(record => {
return <li className="collection-item">
{record}
</li>
})}
</ul>
</div>
)
return (
<div>
<form onSubmit={filteredRecord}>
<input type="text" name='text' value={search} placeholder='Filter from...' onChange={onChange} />
</form>
{!loading ? renderFilter : <div></div>}
</div>
)
The fetching works fine and renders. I want to filter and map properly below is a screenshot
You have not passed records as props in RecordsFilter.
return (
<Fragment>
<SearchBar />
<div className='container'>
<h2>Patients Record Details</h2>
<RecordsFilter records={currentRecords} />
<Pagination recordsPerPage={recordsPerPage} totalRecords={records.length} paginate={paginate} />
{!loading ? <Records loading={loading} records={currentRecords} /> : <div></div>}
</div>
</Fragment>
);
}

reactjs component called multiple times

I am working with Reactjs to pull information from a database and then display it in a pdf. I keep running into issues, and I think I have narrowed it down to where it is coming from, but not sure what is causing the issue.
In the following image you will note that I have a repeat of three console logs which is "list" and "provider".
The code for the main app is:
import Header from './components/top/header'
import List from './components/list'
import {GroceryDataProvider} from './context/DataContext'
function App() {
console.log('app')
return(
<div>
<h1>React Testing App</h1>
<GroceryDataProvider>
<Header/>
<List/>
</GroceryDataProvider>
</div>)
}
export default App;
the console.log "provider" is coming from my GroceryDataProvider. It is just a basic console log at the very top of it. Inside is one useEffect() and several functions. The following is the useEffect for DataProvider:
console.log('Provider')
const [groceryList, setGroceryList] = useState([]);
const [userList, setUserList] = useState([]);
const [userGroceryList, setUserGroceryList] = useState([]);
const [userItemList, setUserItemList] = useState([]);
const [userTypeList, setUserTypeList] = useState([]);
const [listId, setListId] = useState('');
const [userId, setUserId] = useState('');
const [DataLoad, setDataLoad] = useState(false);
//const [a, setA] = useState([]);
//const [lId, setLId] = useState(0);
useEffect(()=>{
console.log('effec')
const fetch = async()=>{
let db = firebase.database().ref('groceryA/');
db.once('value',snapshot=>{
snapshot.forEach(child=>{
setGroceryList(list=>[...list,child.val()])
})
})
db = firebase.database().ref('users/');
db.once('value',snapshot=>{
setUserList(snapshot.val());
})
db = firebase.database().ref('categories')
db.once('value',snapshot=>{
setUserTypeList(snapshot.val());
})
}
fetch();
},[])
//functions are here
const GetList = () => {
console.log('GETLIST');
setUserItemList([])
let db = firebase.database().ref('groceryA/'+listId+'/items');
db.once('value',snapshot=>{
snapshot.forEach(item=>{
setUserItemList(list=>[...list,item.val()])
})
})
}
return(
<DataContext.Provider value={{groceryList,userList,userGroceryList,userItemList,listId,userId,userTypeList,DataLoad,
setGroceryList,setUserList,setListId,setUserId,setUserTypeList,
ChangeUser,GetUserList,ChangeList,GetItemList,Updater,UpdateCart,WriteItem,WriteList,GetList,Delete}}>
{props.children}
</DataContext.Provider>
)
}
The other repeat console.log is "list" which again is just a basic console.log at the top of another component.
import React, {useContext,useEffect,useState} from 'react';
import { PDFDownloadLink, PDFViewer, Document, Page, Text } from '#react-pdf/renderer'
import MyDocument from './pdf';
import {DataContext} from 'context/DataContext'
import Card from './ItemCard';
const List = () =>{
console.log('list')
const {listId} = useContext(DataContext);
const {userItemList} = useContext(DataContext);
// {GetItemList} = useContext(DataContext);
const {Updater} = useContext(DataContext);
const {GetList} = useContext(DataContext);
const {Delete} = useContext(DataContext);
const {UpdateCart} = useContext(DataContext);
const [items, SetItems] = useState([]);
useEffect(()=>{
console.log('list id')
GetList();
},[listId])
useEffect(()=>{
console.log(userItemList)
console.log('item list')
SetItems([]);
SetItems(userItemList)
},[userItemList])
const productChange = (itemTxt, itemId) => {
SetItems(items.map(item=>{
if(item.listItemId===itemId){
return{...item,product:itemTxt}
}
return item;
}
))
}
const quantityChange = (itemTxt, itemId) => {
SetItems(items.map(item=>{
if(item.listItemId===itemId){
return{...item,quantity:itemTxt}
}
return item;
}
))
}
const cartChange = (itemId) => {
SetItems(items.map(item=>{
if(item.listItemId===itemId){
UpdateCart({...item,cart:!item.cart},item.listItemId)
return{...item,cart:!item.cart}
//console.log(item)
}
return item;}
//console.log(item)
}
))
}
return(
<div>
<p>To Find:</p>
<ul>
{//console.log(items)
}
{items.map((item,index)=>item.cart===false?
<Card key={item.listItemId} index={index}
value={item.listItemId} cart={item.cart} item={item.product}
units={item.quantity} unitType={item.unit}
cartChange={cartChange} itemChange={productChange} quantityChange={quantityChange} change={Updater} delete={Delete}/>:null)}
</ul>
<p>Found</p>
<ul>
{items.map((item,index)=>item.cart===true?<Card key={item.listItemId} index={index}
value={item.listItemId} cart={item.cart} item={item.product}
units={item.quantity} unitType={item.unit}
cartChange={cartChange} itemChange={productChange} quantityChange={quantityChange} change={Updater} delete={Delete}/>:null)}
</ul>
</div>
)
}
export default List;
What I don't understand is why only the context and list are repeating. I have another component called head which only renders once (third line down in the photo "head"). I thought it might have something to do with my useEffect inside the list component, but that is only called when there is a change, which does not happen at this point.
UPDATE
including Header component in response to alverio:
import {DataContext} from 'context/DataContext'
const UserSelect = () => {
const {userList} = useContext(DataContext);
const {ChangeUser} = useContext(DataContext);
return(
<div>
<select defaultValue={'default'} onChange={(e)=>ChangeUser(e.target.value)}>
<option value='default' disabled>Select a user</option>
{userList.map(user=>(
<option key={user.id} value={user.id}>{user.name}</option>
))}
</select>
</div>
)
}
const ListSelect = () => {
console.log('ListSelect')
const {GetUserList} = useContext(DataContext);
const {userGroceryList} = useContext(DataContext);
const {userId} = useContext(DataContext);
const {ChangeList} = useContext(DataContext);
useEffect(()=>{
GetUserList();
},[userId])
return (
<div>
<select defaultValue={'default'} onChange={(e)=>{ChangeList(e.target.value)}}>
<option value='default' disabled >Select a grocery list</option>
{userGroceryList.map(list=>(
<option key={list.listId} value={list.listId}>{list.title}</option>))}
</select>
</div>
)
}
const ListAdd = () => {
const {WriteItem} = useContext(DataContext);
const {WriteList} = useContext(DataContext);
const {userId} = useContext(DataContext);
const {userTypeList} = useContext(DataContext);
const [item, setItem] = useState('');
const [product, setProduct] = useState('');
const [quantity, setQuantity] = useState('');
const [category, setCategory] = useState('');
const [type, setType] = useState('');
let measureCategory = ['Each', 'Lb', 'Oz', 'Fl Oz']
let dataCategory = ['Other','Beverages', 'Bakery', 'Canned Goods', 'Dairy', 'Baking Goods', 'Frozen Foods', 'Meat', 'Produce', 'Snacks'];
console.log('ListAdd')
return (
<div>
<div>
<input id="list" type="text" value={item} onChange={(e)=>setItem(e.target.value)}/>
<button type="button" onClick={(e)=>{WriteList(item)}}>New List</button>
</div>
<div>
<input type="text" value={product} onChange={(e)=>setProduct(e.target.value)}/>
<select defaultValue={'default'} onChange={(e)=>{setCategory(e.target.value)}}>
<option value='default' disabled >Select a category</option>
{userTypeList.map(ul=>ul.id===parseInt(userId)?(ul.categories.map((uc,index)=><option key={index} value={uc}>{uc}</option>)):null)}</select>
<br/>
<input type="number" value={quantity} onChange={(e)=>setQuantity(e.target.value)}/>
<select defaultValue={'default'} onChange={(e)=>{setType(e.target.value)}}>
<option value='default' disabled >Select a unit</option>
{measureCategory.map((mc,index)=><option key={index} value={mc}>{mc}</option>)}</select>
<button type="button" onClick={(e)=>{WriteItem(product,category,quantity,type)}}>New Item</button>
</div>
</div>
)
}
const Header = () => {
console.log('head')
return (
<div>
<div>
<UserSelect/>
</div>
<div>
<ListSelect/>
</div>
<div>
<ListAdd/>
</div>
</div>
)
}
export default Header;

Categories