Does not see the function when outputting reactjs - javascript

On the main page without a Header, this function works. I want to make it on a separate page, it doesn't work.
I looked at examples, everything converges, does not display on a separate page.
Аrom addpeople to add, header(example <\h1>text<\h1> or other works.
\addpeople.js
import React, { Component } from 'react';
import "./add.css";
import { useState } from "react";
import Axios from "axios";
import { Button } from "react-bootstrap";
import 'bootstrap/dist/css/bootstrap.min.css';
function newcreate() {
return (
function App() {
const [surename_ru, setSurename_ru] = useState("");
const [name_ru, setName_ru] = useState(0);
const [fname_ru, setFname_ru] = useState("");
const [surename_en, setSurename_en] = useState("");
const [name_en, setName_en] = useState(0);
const [gender, setGender] = useState("");
const [dateofbirth, setDateofbirth] = useState(0);
const [citizenship, setCitizenship] = useState("");
const [pas_ser, setPas_ser] = useState("");
const [pas_num, setPas_num] = useState(0);
const [pas_start, setPas_start] = useState("");
const [pas_end, setPas_end] = useState(0);
const [pas_given, setPas_given] = useState("");
const [pas_givenkod, setPas_givenkod] = useState("");
const [inn_num, setInn_num] = useState(0);
const [snils_num, setSnils_num] = useState("");
const [legal_type, setLegal_type] = useState(0);
const [newWage, setNewWage] = useState(0);
const [employeeList, setEmployeeList] = useState([]);
const addEmployee = () => {
Axios.post("http://localhost:3001/create", {
surename_ru: surename_ru,
name_ru: name_ru,
fname_ru: fname_ru,
surename_en: surename_en,
name_en: name_en,
gender: gender,
dateofbirth: dateofbirth,
citizenship: citizenship,
pas_ser: pas_ser,
pas_num: pas_num,
pas_start: pas_start,
pas_end: pas_end,
pas_given: pas_given,
pas_givenkod: pas_givenkod,
inn_num: inn_num,
snils_num: snils_num,
legal_type: legal_type,
}).then(() => {
setEmployeeList([
...employeeList,
{
surename_ru: surename_ru,
name_ru: name_ru,
fname_ru: fname_ru,
surename_en: surename_en,
name_en: name_en,
gender: gender,
dateofbirth: dateofbirth,
citizenship: citizenship,
pas_ser: pas_ser,
pas_num: pas_num,
pas_start: pas_start,
pas_end: pas_end,
pas_given: pas_given,
pas_givenkod: pas_givenkod,
inn_num: inn_num,
snils_num: snils_num,
legal_type: legal_type,
},
]);
});
};
const getEmployees = () => {
Axios.get("http://localhost:3001/employees").then((response) => {
setEmployeeList(response.data);
});
};
const updateEmployeeWage = (id) => {
Axios.put("http://localhost:3001/update", { wage: newWage, id: id }).then(
(response) => {
setEmployeeList(
employeeList.map((val) => {
return val.id == id
? {
surename_ru: val.surename_ru,
name_ru: val.name_ru,
fname_ru: val.fname_ru,
surename_en: val.surename_en,
name_en: val.name_en,
gender: val.gender,
dateofbirth: val.dateofbirth,
citizenship: val.citizenship,
pas_ser: val.pas_ser,
pas_num: val.pas_num,
pas_start: val.pas_start,
pas_end: val.pas_end,
pas_given: val.pas_given,
pas_givenkod: val.pas_givenkod,
inn_num: val.inn_num,
snils_num: val.snils_num,
legal_type: val.legal_type,
}
: val;
})
);
}
);
};
const deleteEmployee = (id) => {
Axios.delete(`http://localhost:3001/delete/${id}`).then((response) => {
setEmployeeList(
employeeList.filter((val) => {
return val.id != id;
})
);
});
};
return (
<div className="App">
<div className="information">
<label>Фамилия</label>
<input
type="text"
onChange={(event) => {
setSurename_ru(event.target.value);
}}
/>
<label>Имя РУС</label>
<input
type="text"
onChange={(event) => {
setName_ru(event.target.value);
}}
/>
<label>Отчество</label>
<input
type="text"
onChange={(event) => {
setFname_ru(event.target.value);
}}
/>
<label>Surename EN</label>
<input
type="text"
onChange={(event) => {
setSurename_en(event.target.value);
}}
/>
<label>Name EN</label>
<input
type="text"
onChange={(event) => {
setName_en(event.target.value);
}}
/>
<label>gender</label>
<input
type="text"
onChange={(event) => {
setGender(event.target.value);
}}
/>
<label>Data ROJD</label>
<input
type="text"
onChange={(event) => {
setDateofbirth(event.target.value);
}}
/>
<label>Citizenship</label>
<input
type="text"
onChange={(event) => {
setCitizenship(event.target.value);
}}
/>
<label>Pas SER</label>
<input
type="text"
onChange={(event) => {
setPas_ser(event.target.value);
}}
/>
<label>Pas NUM</label>
<input
type="text"
onChange={(event) => {
setPas_num(event.target.value);
}}
/>
<label>Pas Start</label>
<input
type="text"
onChange={(event) => {
setPas_start(event.target.value);
}}
/>
<label>Pas End</label>
<input
type="text"
onChange={(event) => {
setPas_end(event.target.value);
}}
/>
<label>Pas Given</label>
<input
type="text"
onChange={(event) => {
setPas_given(event.target.value);
}}
/>
<label>Pas Givenkod</label>
<input
type="text"
onChange={(event) => {
setPas_givenkod(event.target.value);
}}
/>
<label>inn_num</label>
<input
type="text"
onChange={(event) => {
setInn_num(event.target.value);
}}
/>
<label>snils_num</label>
<input
type="text"
onChange={(event) => {
setSnils_num(event.target.value);
}}
/>
<label>legal Type</label>
<input
type="text"
onChange={(event) => {
setLegal_type(event.target.value);
}}
/>
<button onClick={addEmployee}>Add Employee</button>
</div>
<div className="employees">
<button onClick={getEmployees}>Show Employees</button>
{employeeList.map((val, key) => {
return (
<div className="employee">
<div>
<h3>surename_ru: val.surename_ru</h3>
<h3>name_ru: val.name_ru</h3>
<h3>fname_ru: val.fname_ru</h3>
<h3>surename_en: val.surename_en</h3>
<h3>name_en: val.name_en</h3>
<h3>gender: val.gender</h3>
<h3>dateofbirth: val.dateofbirth</h3>
<h3>citizenship: val.citizenship</h3>
<h3>pas_ser: val.pas_ser</h3>
<h3>pas_num: val.pas_num</h3>
<h3>pas_start: val.pas_start</h3>
<h3>pas_end: val.pas_end</h3>
<h3>pas_given: val.pas_given</h3>
<h3>pas_givenkod: val.pas_givenkod</h3>
<h3>inn_num: val.inn_num</h3>
<h3>snils_num: val.snils_num</h3>
<h3>legal_type: val.legal_type</h3>
</div>
<div>
<input
type="text"
placeholder="2000..."
onChange={(event) => {
setNewWage(event.target.value);
}}
/>
<button variant="primary"
onClick={() => {
updateEmployeeWage(val.id);
}}
>
{" "}
Update
</button>
<button variant="primary"
onClick={() => {
deleteEmployee(val.id);
}}
>
Delete
</button>
</div>
</div>
);
})}
</div>
</div>
);
}
)
}
export default newcreate;
\add.js
import React, { Component } from 'react';
import newcreate from './addpeople';
function add() {
return (
<div>
<div>
<newcreate />
</div>
</div>
);
}
export default add;

You are trying to return hooks and functions from a functions return(). But instead you need to do that outside of return, so that your logic works. You can refer react hook docs here: https://reactjs.org/docs/hooks-overview.html#:~:text=Hooks%20are%20functions%20that%20let,if%20you'd%20like.)
For your code you can try something like this:
import React, { Component } from "react";
import "./add.css";
import { useState } from "react";
import Axios from "axios";
import { Button } from "react-bootstrap";
import "bootstrap/dist/css/bootstrap.min.css";
function newcreate() {
function App() {
const [surename_ru, setSurename_ru] = useState("");
const [name_ru, setName_ru] = useState(0);
const [fname_ru, setFname_ru] = useState("");
const [surename_en, setSurename_en] = useState("");
const [name_en, setName_en] = useState(0);
const [gender, setGender] = useState("");
const [dateofbirth, setDateofbirth] = useState(0);
const [citizenship, setCitizenship] = useState("");
const [pas_ser, setPas_ser] = useState("");
const [pas_num, setPas_num] = useState(0);
const [pas_start, setPas_start] = useState("");
const [pas_end, setPas_end] = useState(0);
const [pas_given, setPas_given] = useState("");
const [pas_givenkod, setPas_givenkod] = useState("");
const [inn_num, setInn_num] = useState(0);
const [snils_num, setSnils_num] = useState("");
const [legal_type, setLegal_type] = useState(0);
const [newWage, setNewWage] = useState(0);
const [employeeList, setEmployeeList] = useState([]);
const addEmployee = () => {
Axios.post("http://localhost:3001/create", {
surename_ru: surename_ru,
name_ru: name_ru,
fname_ru: fname_ru,
surename_en: surename_en,
name_en: name_en,
gender: gender,
dateofbirth: dateofbirth,
citizenship: citizenship,
pas_ser: pas_ser,
pas_num: pas_num,
pas_start: pas_start,
pas_end: pas_end,
pas_given: pas_given,
pas_givenkod: pas_givenkod,
inn_num: inn_num,
snils_num: snils_num,
legal_type: legal_type,
}).then(() => {
setEmployeeList([
...employeeList,
{
surename_ru: surename_ru,
name_ru: name_ru,
fname_ru: fname_ru,
surename_en: surename_en,
name_en: name_en,
gender: gender,
dateofbirth: dateofbirth,
citizenship: citizenship,
pas_ser: pas_ser,
pas_num: pas_num,
pas_start: pas_start,
pas_end: pas_end,
pas_given: pas_given,
pas_givenkod: pas_givenkod,
inn_num: inn_num,
snils_num: snils_num,
legal_type: legal_type,
},
]);
});
};
const getEmployees = () => {
Axios.get("http://localhost:3001/employees").then((response) => {
setEmployeeList(response.data);
});
};
const updateEmployeeWage = (id) => {
Axios.put("http://localhost:3001/update", { wage: newWage, id: id }).then(
(response) => {
setEmployeeList(
employeeList.map((val) => {
return val.id == id
? {
surename_ru: val.surename_ru,
name_ru: val.name_ru,
fname_ru: val.fname_ru,
surename_en: val.surename_en,
name_en: val.name_en,
gender: val.gender,
dateofbirth: val.dateofbirth,
citizenship: val.citizenship,
pas_ser: val.pas_ser,
pas_num: val.pas_num,
pas_start: val.pas_start,
pas_end: val.pas_end,
pas_given: val.pas_given,
pas_givenkod: val.pas_givenkod,
inn_num: val.inn_num,
snils_num: val.snils_num,
legal_type: val.legal_type,
}
: val;
})
);
}
);
};
const deleteEmployee = (id) => {
Axios.delete(`http://localhost:3001/delete/${id}`).then((response) => {
setEmployeeList(
employeeList.filter((val) => {
return val.id != id;
})
);
});
};
return (
<div className="App">
<div className="information">
<label>Фамилия</label>
<input
type="text"
onChange={(event) => {
setSurename_ru(event.target.value);
}}
/>
<label>Имя РУС</label>
<input
type="text"
onChange={(event) => {
setName_ru(event.target.value);
}}
/>
<label>Отчество</label>
<input
type="text"
onChange={(event) => {
setFname_ru(event.target.value);
}}
/>
<label>Surename EN</label>
<input
type="text"
onChange={(event) => {
setSurename_en(event.target.value);
}}
/>
<label>Name EN</label>
<input
type="text"
onChange={(event) => {
setName_en(event.target.value);
}}
/>
<label>gender</label>
<input
type="text"
onChange={(event) => {
setGender(event.target.value);
}}
/>
<label>Data ROJD</label>
<input
type="text"
onChange={(event) => {
setDateofbirth(event.target.value);
}}
/>
<label>Citizenship</label>
<input
type="text"
onChange={(event) => {
setCitizenship(event.target.value);
}}
/>
<label>Pas SER</label>
<input
type="text"
onChange={(event) => {
setPas_ser(event.target.value);
}}
/>
<label>Pas NUM</label>
<input
type="text"
onChange={(event) => {
setPas_num(event.target.value);
}}
/>
<label>Pas Start</label>
<input
type="text"
onChange={(event) => {
setPas_start(event.target.value);
}}
/>
<label>Pas End</label>
<input
type="text"
onChange={(event) => {
setPas_end(event.target.value);
}}
/>
<label>Pas Given</label>
<input
type="text"
onChange={(event) => {
setPas_given(event.target.value);
}}
/>
<label>Pas Givenkod</label>
<input
type="text"
onChange={(event) => {
setPas_givenkod(event.target.value);
}}
/>
<label>inn_num</label>
<input
type="text"
onChange={(event) => {
setInn_num(event.target.value);
}}
/>
<label>snils_num</label>
<input
type="text"
onChange={(event) => {
setSnils_num(event.target.value);
}}
/>
<label>legal Type</label>
<input
type="text"
onChange={(event) => {
setLegal_type(event.target.value);
}}
/>
<button onClick={addEmployee}>Add Employee</button>
</div>
<div className="employees">
<button onClick={getEmployees}>Show Employees</button>
{employeeList.map((val, key) => {
return (
<div className="employee">
<div>
<h3>surename_ru: val.surename_ru</h3>
<h3>name_ru: val.name_ru</h3>
<h3>fname_ru: val.fname_ru</h3>
<h3>surename_en: val.surename_en</h3>
<h3>name_en: val.name_en</h3>
<h3>gender: val.gender</h3>
<h3>dateofbirth: val.dateofbirth</h3>
<h3>citizenship: val.citizenship</h3>
<h3>pas_ser: val.pas_ser</h3>
<h3>pas_num: val.pas_num</h3>
<h3>pas_start: val.pas_start</h3>
<h3>pas_end: val.pas_end</h3>
<h3>pas_given: val.pas_given</h3>
<h3>pas_givenkod: val.pas_givenkod</h3>
<h3>inn_num: val.inn_num</h3>
<h3>snils_num: val.snils_num</h3>
<h3>legal_type: val.legal_type</h3>
</div>
<div>
<input
type="text"
placeholder="2000..."
onChange={(event) => {
setNewWage(event.target.value);
}}
/>
<button
variant="primary"
onClick={() => {
updateEmployeeWage(val.id);
}}
>
{" "}
Update
</button>
<button
variant="primary"
onClick={() => {
deleteEmployee(val.id);
}}
>
Delete
</button>
</div>
</div>
);
})}
</div>
</div>
);
}
}
Hope this helps!

function App() {
const [surename_ru, setSurename_ru] = useState("");
const [name_ru, setName_ru] = useState(0);
const [fname_ru, setFname_ru] = useState("");
const [surename_en, setSurename_en] = useState("");
const [name_en, setName_en] = useState(0)....
export default App;
Problem solved, thanks.

Related

reactjs – REACT – Set initial data in Formik Form after fetching from API

Call for help - I am trying to handle initial data in formik after fetching from API, the form reading initial values but did not after fetching .
i am using useEffect .
Moreover, i am using document addEventListener to handle input search keydown event, i know it is not best practise in React if any body check code and give advice what's problem in form and how to handle input search ref with state.
import React, { useEffect, useState } from 'react';
import { Formik, Form, FastField } from 'formik';
import SearchOutlinedIcon from "#mui/icons-material/SearchOutlined";
import * as yup from 'yup';
import axios from 'axios';
import "./edit.scss";
import Loading from "../Loading";
import Swal from 'sweetalert2';
const validation = yup.object().shape({
emp_no: yup.number().required(""),
name: yup.string().required(""),
project: yup.string().required(""),
nationality: yup.string().required(""),
iqama_no: yup.number().required(""),
room_no: yup.number().required(""),
zoon_no: yup.number().required(""),
in_date: yup.date().required(""),
in_reason: yup.string().required(""),
out_date: yup.date()
});
const initialValues = {
emp_no: "",
name: "",
project: "",
nationality: "",
iqama_no: "",
room_no: "",
zoon_no: "",
in_date: "",
in_reason: "",
out_date: "",
};
const EditAlameia = () => {
const [query, setQuery] = useState("");
const [data, setData] = useState([]);
const [loading, setLoading] = useState(false);
useEffect(() => {
const fetchData = async (event) => {
if (event.keyCode === 13) {
event.preventDefault();
setLoading(true);
await axios.get(`http://localhost:3001/alameia/search/edit?q=${query}`).then((res) => {
console.log(res.data);
setData(res.data);
}).catch((err) => {
if (err.response) {
console.log(err.response.data);
console.log(err.response.status);
} else if (err.request) {
console.log(err.request);
} else {
console.log('Error', err.message);
}
}).finally(() => setLoading(false));
}
};
document.addEventListener('keydown', fetchData);
return () => {
document.removeEventListener('keydown', fetchData);
}
}, [query]);
if (loading) {
return (
<Loading />
)
}
return (
<div className="searchNew">
<div className="top">
<h5 >Edit Data</h5>
<div className="searchInput">
<input
type="text"
placeholder="بحث"
id="search"
value={query}
onChange={(e) => { setQuery(e.target.value) }}
/>
<SearchOutlinedIcon />
</div>
</div>
{(data !== undefined) ?
<Formik
initialValues={data || initialValues}
validationSchema={validation}
enableReinitialize
>
{formik => {
console.log(data)
return (
<Form encType='multipart/form-data'>
<div className="bottom">
<div className="right">
<label htmlFor="emp_no" >الرقم الوظيفي</label>
<FastField
type='number'
name='emp_no'
id="emp_no"
/>
<label htmlFor="name" >الإسم</label>
<FastField
type='text'
name='name'
id="name"
/>
<label htmlFor="project" >المشروع </label>
<FastField
type='text'
name='project'
id="project"
/>
<label htmlFor="nationality" >الجنسية </label>
<FastField
type='text'
name='nationality'
id="nationality"
/>
<button type='submit' className="btn btn-danger" >Update</button>
</div>
<div className="left">
<div className="room">
<label htmlFor="room">رقم </label>
<FastField
autoComplete="off"
className="formInput"
type="number" id="room_no" name="room_no" placeholder=""
/>
<label htmlFor="zoon">زون </label>
<FastField
className="formInput" type="number" id="zoon_no"
name="zoon_no" placeholder=""
/>
</div>
<label htmlFor="in_date">تاريخ التسكين</label>
<FastField
type='date'
name='in_date'
id="in_date"
/>
<label htmlFor="iqama_no" >رقم الإقامة </label>
<FastField
type='number'
name='iqama_no'
id="iqama_no"
/>
<label htmlFor="in_reason" >سبب التسكين</label>
<FastField
type='text'
name='in_reason'
id="in_reason"
/>
<label htmlFor="out_date" >تاريخ الخروج</label>
<FastField
type='date'
name='out_date'
id="out_date"
/>
</div>
</div>
</Form>
)
}}
</Formik>
:<div style={{fontSize: "14px", color:"crimson"}}>Not available</div>
}
</div>
)
}
export default EditAlameia;
I'm not sure if this solves your issue, but the main issue I currently see in your component is the fact that you are using addEventListener().
Instead of listening for an "keydown" event and checking for Enter (eg. keyCode 13), you could place your <input> in a <form> (which is submitted on Enter) and add an onSubmit event via React.
.spinner {
/* just to push the spinner away from the search bar */
margin-top: 1em;
width: 2em;
height: 2em;
border-top: 2px solid black;
border-radius: 50%;
animation: 1s linear infinite spin;
}
#keyframes spin {
from { transform: rotate(0turn) }
to { transform: rotate(1turn) }
}
/* keep the snippet console small */
div.as-console-wrapper { max-height: calc(1em + 9px) }
<script type="text/babel">
const { useState } = React;
const SPOOF_DATA = [
{ id: 1, label: "John Doe" },
{ id: 2, label: "Jane Doe" },
{ id: 3, label: "foo" },
{ id: 4, label: "foo bar" },
{ id: 5, label: "foo bar baz" },
{ id: 6, label: "yo" },
];
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
const randomInt = limit => Math.floor(Math.random() * limit);
function Loading() {
return <div className="spinner" />;
}
function App() {
const [query, setQuery ] = useState("");
const [isLoading, setIsLoading] = useState(false);
const [data, setData ] = useState([]);
async function fetchSearchResults(e) {
e.preventDefault();
setIsLoading(true);
try {
console.log("fetch data using query", JSON.stringify(query));
// const res = await axios.get(`http://localhost:3001/alameia/search/edit?q=${query}`);
// setData(res.data);
await sleep(1000 + randomInt(2000));
setData(SPOOF_DATA.filter(({ label }) => label.includes(query)));
} catch (err) {
if (err.response) {
console.log(err.response.data);
console.log(err.response.status);
} else if (err.request) {
console.log(err.request);
} else {
console.log('Error', err.message);
}
} finally {
setIsLoading(false);
}
}
return (
<>
<form onSubmit={fetchSearchResults}>
<input value={query} onChange={e => setQuery(e.target.value)} />
</form>
{isLoading ? (
<Loading />
) : (
<ul>
{data.map(({ id, label }) => (
<li key={id}>{label}</li>
))}
</ul>
)}
</>
);
}
ReactDOM.createRoot(document.querySelector("#root")).render(<App />);
</script>
<script crossorigin src="https://unpkg.com/react#18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom#18/umd/react-dom.development.js"></script>
<script crossorigin src="https://unpkg.com/#babel/standalone#7/babel.min.js"></script>
<div id="root"></div>

I am not getting synthetic event while using in onChange in react js

I am trying to select the product in the dropdown menu and increase the quantity as well. But I am unable to select them. In the onChange function, the event object I am getting is undefined. And an error is as follows.
Uncaught TypeError: Cannot read properties of undefined (reading
'name')
And code as follows:
import React, { useEffect, useState } from 'react'
import { useSelector, useDispatch } from 'react-redux'
import { startCraeteBill } from '../../actions/billAction'
import Select from 'react-select'
import BillsList from './BillsList'
const AddBill = (props) => {
const customers = useSelector(state => state.customers)
const products = useSelector(state => state.products)
const dispatch = useDispatch()
const [formValues, setFormValues] = useState([{ product: "", quantity: 1 }])
const [_id, set_Id] = useState('')
const [cust, setCust] = useState('')
const [total, setTotal] = useState(0)
const handleChange = (e, i) => {
const newFormvalues = [...formValues]
console.log('e', e, i)
newFormvalues[i][e.target.name] = e.target.value
console.log('add bill', newFormvalues)
setFormValues(newFormvalues)
}
const addFormFields = () => {
const newFormvalues = [...formValues, { product: '', quantity: 1 }]
setFormValues(newFormvalues)
}
const removeFormFields = (i) => {
const newFormvalues = formValues.filter((ele, index) => { return index !== i })
setFormValues(newFormvalues)
}
const handleSubmit = (e) => {
e.preventDefault()
const todayDate = new Date().toISOString.slice(0, 10)
const formData = {
date: todayDate, customer: _id, lineItems: [...formValues]
}
dispatch(startCraeteBill(formData, resetForm))
setTotal(0)
}
const subTotalFun = (product, quantity) => {
return products.data.find(ele => ele._id === product).price * quantity
}
const handleId = (cust) => {
setCust(cust)
set_Id(cust._id)
}
const resetForm = () => {
setFormValues([{ product: '', quantity: 1 }])
set_Id('')
}
console.log('form values', formValues)
useEffect(() => {
if (formValues.every(ele => ele.product)) {
let total = 0
formValues.forEach(ele => { total += subTotalFun(ele.product, ele.quantity) })
setTotal(total)
}
}, [formValues])
return (<div>
<div className="border shadow rounded p-2" style={{ color: '#66FCF1', backgroundColor: '#2F363F' }}>
<h2 className=" d-inline">Add Bills</h2><h2 className="d-inline m-3" style={{ float: 'right' }}>Total:{total}</h2>
<form onSubmit={handleSubmit}>
<div style={{ width: '40%', color: 'black' }} className="m-2">
<Select name="customer" options={customers.data} placeholder="--Select Customer--" value={customers.data.filter(function (option) {
return option.name === cust.name
})} getOptionLabel={(option) => option.name} label={(option) => option.name}
getOptionValue={(option) => option._id}
onChange={handleId}
/>
</div>
{
formValues.map((ele, index) => (
<div className="form-inline " key={index}>
<select className='form-select d-inline m-2' name='product' value={ele.product || ''} style={{ width: '40%' }} onChange={() => {handleChange(index)}}>
<option>--Select Product--</option>
{
products.data.map((ele, i) => {
return <option key={ele._id} value={ele._id}>{ele.name}</option>
})
}
</select>
<input type='number' className="form-control d-inline m-2 " name='quantity' min="1" max="99" placeholder="Quantity" value={ele.quantity || ""} onChange={() => {handleChange(index)}} style={{ width: '20%' }} />
{ele.product && <h5 className="d-inline p-2">{subTotalFun(ele.product, ele.quantity)}</h5>}
{
index ? <button type="button" className="button remove btn btn-danger m-2 " onClick={() => removeFormFields(index)}>Remove</button>
: null
}
</div>
))
}
<div className="botton-section">
<button className="button add btn btn-warning m-2" onClick={() => addFormFields()}>Add</button>
<button className="button submit btn btn-primary m-2" type="submit">Submit</button>
</div>
</form>
<div>
<BillsList _id={_id} />
</div>
</div>
</div>)
}
export default AddBill
this is the error I am getting while selecting from the dropdown
You are not passing event as a parameter in your onChange function
onChange((e) => handleChange(e, index))

creating unique id into object without UUID in React

I am trying to test my understanding of React but hit a mental block. Would it be possible to create a unique key / id within my <FormInput> component rather than creating the unique ID inside the <MainUI> component once the newly created item is passed up into <MainUI>? I find that weird and definitely feel like there is a way better method of doing this.
const MainUI = props => {
const receiveNewItem = enteredNewItem => {
const newItem = {
...enteredNewItem,
id: Math.random().toString()
}
props.addNewItem(newItem)
}
console.log(props.data)
return(
<div>
<FormInput receiveNewItem={receiveNewItem}/>
{/* <MaxAmount data={props.data} /> */}
<DisplayItems data={props.data} key={props.data.id} />
</div>
)
}
export default MainUI;
import { useState } from 'react'
import Card from './Card'
const FormInput = props => {
const [userInput, setUserInput] = useState({
name: '',
amount: '',
date: ''
})
const nameInputHandler = e => {
setUserInput( prevObj => {
return {...prevObj, name: e.target.value}
})
}
const amountInputHandler = e => {
setUserInput( prevObj => {
return {...prevObj, amount: e.target.value}
})
}
const dateInputHandler = e => {
setUserInput( prevObj => {
return {...prevObj, date: e.target.value}
})
}
const submitHandler = e => {
e.preventDefault()
props.receiveNewItem(userInput)
setUserInput( prevObj => { return {...prevObj, name: ''}})
}
return (
<Card>
<form onSubmit={submitHandler}>
<input
type="text"
placeholder="Name Input"
value={userInput.name}
onChange={nameInputHandler} />
<input
type="number"
placeholder="Amount Input"
value={userInput.amount}
onChange={amountInputHandler} />
<input
type="date"
placeholder="Date Input"
value={userInput.date}
onChange={dateInputHandler} />
<button>Add Item</button>
</form>
</Card>
)
}
export default FormInput;

After editing only one field is edited and the other one behaves unexpectedly (React hooks)

I have very simple ediable book-list. But when I press 'edit' and edit just one of two fields the other one behaves unexpectedly (it clears out even tho there was a value, or takes unexpected value from God knows where). It works correctly only if I edit both fields at once.
Here's my code:
import './App.css';
import React, { useState, useEffect } from 'react';
function App() {
const [books, setBooks] = useState([]);
const [book, setBook] = useState({
id: '',
title: '',
author: ''
});
const [alertMessage, setAlertMessage] = useState(false);
const [successMessage, setSuccessMessage] = useState(false);
const [editMode, setEditMode] = useState(null);
const [titleValue, setTitleValue] = useState('');
const [authorValue, setAuthorValue] = useState('');
useEffect(()=> {
const data = localStorage.getItem('books');
if(data) {
setBooks(JSON.parse(data))
}
}, [])
useEffect(()=> {
localStorage.setItem('books', JSON.stringify(books))
},)
function addBook (e) {
e.preventDefault();
if(!book.title && !book.author){
setAlertMessage(true)
setTimeout(()=>setAlertMessage(false), 3000)
} else {
let newBook = {
...book,
id: Math.floor(Math.random() * 100000000),
};
setBooks([newBook, ...books]);
setBook({
title: '',
author: ''
});
setSuccessMessage(true)
setTimeout(()=>setSuccessMessage(false), 1000);
}
}
function deleteBook(id){
setBooks(books.filter(book => book.id !== id))
}
function editBook(id) {
setEditMode(id);
}
function onChange(e) {
setBook({
...book,
[e.target.name]: e.target.value
})
}
function saveChanges (id) {
let newBook = [...books].map(book => {
if(book.id === id) {
book.title = titleValue;
book.author = authorValue
}
return book
});
setBook(newBook);
setEditMode(null)
}
return (
<div className='container'>
{alertMessage && <div className='alertMeaage'>Please, enter book author or its title</div>}
{successMessage && <div className='successMessage'>Book is successfully added!</div>}
<div className='BookForm'>
<h3>Add book</h3>
<input name='title' type='text' placeholder='Enter book title' value={book.title} onChange={onChange}/>
<input name='author' type='text' placeholder='Enter book author' value={book.author} onChange={onChange}/>
<button className='submitBtn' onClick={addBook}>Send</button>
</div>
<div>
<h4>Recently added books:</h4>
<div key={book.id}>{books.map(book => (
<div className='bookItem'>
{editMode !== book.id ? <><span className='titleAuthor'>Title: </span><i>«{book.title}» </i>
<span className='titleAuthor'>Author: </span> <i>{book.author}</i>
<button onClick={()=>deleteBook(book.id)} className='deleteBtn'>X</button>
<button onClick={()=>editBook(book.id)} className='editBtn'>Edit</button></>
:
<form className='form'>
<input name='title' type='text' defaultValue={book.title} onChange={(e)=> setTitleValue(e.target.value)}/>
<input name='author' type='text' defaultValue={book.author} onChange={(e)=> setAuthorValue(e.target.value)}/>
<button className='saveBtn' onClick={()=>saveChanges(book.id)}>Save</button>
</form>
}
</div>
))}
</div>
</div>
</div>
);
}
export default App;
Thanks a lot in advance!
When you edit new book, authorValue and titleValue still have previous values, so you must setAuthorValue and setTitleValue in editBook function. See below:
function editBook(book) {
setEditMode(book.id);
setTitleValue(book.title);
setAuthorValue(book.author);
}
And handle event:
<button onClick={() => editBook(book)} className="editBtn">
Edit
</button>
All code:
// import './App.css';
import React, { useState, useEffect } from "react";
function App() {
const [books, setBooks] = useState([]);
const [book, setBook] = useState({
id: "",
title: "",
author: ""
});
const [alertMessage, setAlertMessage] = useState(false);
const [successMessage, setSuccessMessage] = useState(false);
const [editMode, setEditMode] = useState(null);
const [titleValue, setTitleValue] = useState("");
const [authorValue, setAuthorValue] = useState("");
useEffect(() => {
const data = localStorage.getItem("books");
if (data) {
setBooks(JSON.parse(data));
}
}, []);
useEffect(() => {
localStorage.setItem("books", JSON.stringify(books));
});
function addBook(e) {
e.preventDefault();
if (!book.title && !book.author) {
setAlertMessage(true);
setTimeout(() => setAlertMessage(false), 3000);
} else {
let newBook = {
...book,
id: Math.floor(Math.random() * 100000000)
};
setBooks([newBook, ...books]);
setBook({
title: "",
author: ""
});
setSuccessMessage(true);
setTimeout(() => setSuccessMessage(false), 1000);
}
}
function deleteBook(id) {
setBooks(books.filter((book) => book.id !== id));
}
function editBook(book) {
setEditMode(book.id);
setTitleValue(book.title);
setAuthorValue(book.author);
}
function onChange(e) {
console.log(e.target.name, e.target.value);
setBook({
...book,
[e.target.name]: e.target.value
});
}
function saveChanges(id) {
let newBook = [...books].map((book) => {
if (book.id === id) {
book.title = titleValue;
book.author = authorValue;
}
return book;
});
setBook(newBook);
setEditMode(null);
}
return (
<div className="container">
{alertMessage && (
<div className="alertMeaage">
Please, enter book author or its title
</div>
)}
{successMessage && (
<div className="successMessage">Book is successfully added!</div>
)}
<div className="BookForm">
<h3>Add book</h3>
<input
name="title"
type="text"
placeholder="Enter book title"
value={book.title}
onChange={onChange}
/>
<input
name="author"
type="text"
placeholder="Enter book author"
value={book.author}
onChange={onChange}
/>
<button className="submitBtn" onClick={addBook}>
Send
</button>
</div>
<div>
<h4>Recently added books:</h4>
<div key={book.id}>
{books.map((book) => (
<div className="bookItem">
{editMode !== book.id ? (
<>
<span className="titleAuthor">Title: </span>
<i>«{book.title}» </i>
<span className="titleAuthor">Author: </span>{" "}
<i>{book.author}</i>
<button
onClick={() => deleteBook(book.id)}
className="deleteBtn"
>
X
</button>
<button onClick={() => editBook(book)} className="editBtn">
Edit
</button>
</>
) : (
<form className="form">
<input
name="title"
type="text"
defaultValue={book.title}
onChange={(e) => setTitleValue(e.target.value)}
/>
<input
name="author"
type="text"
defaultValue={book.author}
onChange={(e) => setAuthorValue(e.target.value)}
/>
<button
className="saveBtn"
onClick={() => saveChanges(book.id)}
>
Save
</button>
</form>
)}
</div>
))}
</div>
</div>
</div>
);
}
export default App;

Show the next data while looping over an array in typescript react

So, I am trying to add some data to two different array in react typescript
const [deviceNames, setDeviceNames] = useState<Array<string>>([])
const [serialNumbers, setSerialNumbers] = useState<Array<string>>([])
I am now looping over both the array here and displaying the content
{deviceNames.length > 0 &&
serialNumbers.length > 0 &&
deviceNames.map(deviceName => {
return serialNumbers.map(serialNumber => {
return (
<CardDevice
deviceName={deviceName}
serialNumber={serialNumber}
/>
)
})
})}
I am adding data to these array by clicking on a button and then showing modal and then like this
onSubmit = (values: any) => {
clearError()
setAddDevice(false)
setDeviceNames(deviceName => [...deviceName, values.deviceName])
setSerialNumbers(serialNumber => [...serialNumber, values.serialNumber])
}
I am using react hook form.
So what i want is whenever i loop over both the arrays, each time it should display the content which was just added in the array the new one not the last one again which was already added and displayed. I hope i am able to make some point here. It does the job but whenever user enters new device after adding one, it add the old one again and then the new one and then again and then again same thing.
i just want to display just one new item which was just last added to an array by the user.
Thanks
Basically i answered my own question:
import React, { useState } from "react";
function App() {
const [addCardData, setAddCardData] = useState("");
const [addCards, setAddCards] = useState<Array<string>>([]);
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setAddCardData(event.target.value);
};
const handleSubmit = (event: React.FormEvent<HTMLFormElement>): void => {
event.preventDefault();
setAddCards(prevState => [...prevState, addCardData]);
};
return (
<div
className="App"
style={{ textAlign: "center", margin: "0 auto", marginTop: "10em" }}
>
<form onSubmit={handleSubmit}>
<input type="text" onChange={handleChange} placeholder="Add any text" />
<button type="submit">Add</button>
</form>
{addCards.map(addCard => (
<h3>{addCard}</h3>
))}
</div>
);
}
export default App;
Here is some more Dynamic Approach:
import React, { useState } from "react";
import { TextInput } from "./components/TextInput";
interface Device {
deviceName: string;
serialNumber: string | number;
}
const App: React.FC = () => {
const [deviceName, setDeviceName] = useState("");
const [serialNumber, setSerialNumber] = useState("");
const [deviceInfos, setDeviceInfos] = useState<Device[]>([]);
const handleDeviceChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setDeviceName(event.target.value);
};
const handleSerialChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setSerialNumber(event.target.value);
};
const handleSubmit = (event: React.FormEvent<HTMLFormElement>): void => {
event.preventDefault();
addDevice();
setDeviceName("");
setSerialNumber("");
};
const addDevice = () => {
const newDevice: Device[] = [
...deviceInfos,
{ deviceName: deviceName, serialNumber: serialNumber }
];
setDeviceInfos(newDevice);
};
return (
<div
className="App"
style={{ textAlign: "center", margin: "0 auto", marginTop: "10em" }}
>
<form onSubmit={handleSubmit}>
<TextInput
type="text"
placeholder="Add Device Name"
handleChange={handleDeviceChange}
value={deviceName}
/>
<TextInput
type="text"
placeholder="Add fuck"
handleChange={handleSerialChange}
value={serialNumber}
/>
<button type="submit">Add</button>
</form>
{deviceInfos.map((device, i) => (
<div key={i}>
<h3>{device.deviceName}</h3>
<h3>{device.serialNumber}</h3>
</div>
))}
</div>
);
};
export default App;
Much Better Approach i used in the production
const ProfileDevices: React.FC<Props> = ({ onSubmit }) => {
const [addDevice, setAddDevice] = useState(false)
const [deviceInfos, setDeviceInfos] = useState<Device[]>([])
const { register, handleSubmit, errors, clearError } = useForm({
mode: 'onSubmit',
})
const addDevices: any = () => {
setAddDevice(true)
}
onSubmit = (values: any) => {
clearError()
setAddDevice(false)
const newDevice: Device[] = [
...deviceInfos,
{ deviceName: values.deviceName, serialNumber: values.serialNumber },
]
setDeviceInfos(newDevice)
}
return (
<ProfileContentContainer>
<ProfileHeader>
<ProfileTitle>Devices</ProfileTitle>
<ProfileActions>
<Button
type="button"
bgType="fill"
size="default"
label="Add Device"
onClick={addDevices}
/>
</ProfileActions>
</ProfileHeader>
{console.log(deviceInfos)}
<DeviceList>
<CardDevice deviceName="Device Name" serialNumber="QR10001123456788" />
<CardDevice deviceName="Device Name" serialNumber="QR10001123456789" />
{deviceInfos.map((device, i) => (
<CardDevice
key={i}
deviceName={device.deviceName}
serialNumber={device.serialNumber}
/>
))}
</DeviceList>
<Modal isActive={addDevice} toggleModal={() => setAddDevice(false)}>
<ModalContent>
<ModalHeader title="Add Device" />
<AuthForm
onSubmit={handleSubmit(onSubmit)}
className="modalAddDeviceForm"
>
<InputText
placeholder="DeviceName"
name="deviceName"
type="text"
register={register({ required: true, maxLength: 10 })}
hasError={errors.deviceName}
errorMessage={
errors.serialNumber ? errors.serialNumber.message : undefined
}
/>
<InputText
placeholder="Serial Number"
name="serialNumber"
type="text"
register={register({ required: true, maxLength: 10 })}
hasError={errors.serialNumber}
errorMessage={
errors.serialNumber ? errors.serialNumber.message : undefined
}
/>
<Button type="submit" bgType="fill" size="default" label="Add" />
</AuthForm>
<ModalActions></ModalActions>
</ModalContent>
</Modal>
</ProfileContentContainer>
)
}
export default ProfileDevices

Categories