How to set state when a button is clicked - reactjs

I want to set user.Id in setDelid when the button is clicked.
<div className="users">
{users.map((user) => {
return (
<div className="users" key={user.Id} >
<p>
Name: {user.Title}, EmpID: {user.EmpID}, ID: {user.Id}
</p>
<button onClick={deleteData} onChange={(user) => setDelid(user.Id)} className="button button4"></button>
</div>
);
})}
</div>

You can use the onClick function to run the deleteData function and set state:
<button onClick={() => handleClick(user.id)} />
const handleClick = (userId: string) => {
setDelid(userId)
deleteData()
}

Related

How can I maintain the order of adding items in react web app?

How can I create an order of adding items. I should be able to add one after the other item during on click. By default it should display the Textarea first and then blockquote ( see below )
a) When a user click on Text area button, it should add one after the blockquote.
b) Then when the user clicks on Code area button, it should add after Textarea. Could someone please advise ?
CSB link: https://codesandbox.io/s/distracted-worker-26jztf?file=/src/App.js
Something similar >> Expected behaviour: https://jsfiddle.net/nve8qdbu/8/
import "./styles.css";
import React, { useState, useEffect } from "react";
import { useNavigate } from "react-router-dom";
import { useForm } from "react-hook-form";
const blogListData = [
{
id: 1,
heading: "React state",
date: "22-May-2022",
tag: "React",
count: "3"
},
{
id: 2,
heading: "Cypress testing detailss",
date: "22-May-2022",
tag: "Cypress",
count: "5"
}
];
const Admin = () => {
const [createImageTag, setImageTag] = useState("");
const [fields, setFields] = useState([{ value: null }]);
const [createCode, setCreateCode] = useState([{ value: null }]);
const [blogList, setBlogList] = useState([]);
const {
register,
handleSubmit,
formState: { errors },
reset
} = useForm();
useEffect(() => {
setBlogList(blogListData);
}, []);
function handleChangeTextArea(i, event) {
const values = [...fields];
values[i].value = event.target.value;
setFields(values);
}
function handleChangeCode(i, event) {
const codeValues = [...createCode];
codeValues[i].value = event.currentTarget.innerText;
setCreateCode(codeValues);
}
function handleTextAreaAdd() {
const values = [...fields];
values.push({ value: null });
setFields(values);
}
function handleCodeAreaAdd() {
const codeValues = [...createCode];
codeValues.push({ value: null });
setCreateCode(codeValues);
}
function handleImageAreaAdd() {
const image = [...createImageTag];
image.push({ value: null });
setCreateCode(image);
}
function handleRemoveText(i) {
const values = [...fields];
values.splice(i, 1);
setFields(values);
}
function handleRemoveCode(i) {
const codeValues = [...createCode];
codeValues.splice(i, 1);
setCreateCode(codeValues);
}
const handleLogout = () => {
localStorage.removeItem("loginEmail");
};
return (
<div id="App">
<div className="parent">
<div className="adminSection">
<h1>Create a new blog</h1>
<div className="row">
<div className="logout">
<img
src="/images/logout.png"
alt="Logout"
onClick={handleLogout}
></img>
</div>
<div className="createBlogSection">
<div className="row">
<button
onClick={() => handleTextAreaAdd()}
className="textAreaBtn"
>
Text Area
</button>
<button
onClick={() => handleCodeAreaAdd()}
className="codeAreaBtn"
>
Code Area
</button>
<button
onClick={() => handleImageAreaAdd()}
className="imageAreaBtn"
>
Add Image
</button>
</div>{" "}
<br></br>
<div className="row">
{fields.map((field, idx) => {
return (
<div key={`${field}-${idx}`} className="dtextArea">
<button
type="button"
onClick={() => handleRemoveText(idx)}
className="closeElement"
>
X
</button>
<textarea
type="text"
id="blogtext"
placeholder="Enter your text here"
className="defaultTextArea"
{...register("blogtext", {
required: true,
minLength: {
value: 25,
message: "Minimum length of 25 letters"
}
})}
value={field.value || ""}
onChange={(e) => handleChangeTextArea(idx, e)}
/>
<span className="validationmsg">
{errors.blogtext &&
errors.blogtext.type === "required" && (
<span>Blog text is required !</span>
)}
{errors.blogtext && (
<span>{errors.blogtext.message}</span>
)}
</span>
</div>
);
})}
</div>
<div className="row">
{createCode.map((code, idx) => {
return (
<div key={`${code}-${idx}`} className="dCodeArea">
<button
type="button"
onClick={() => handleRemoveCode(idx)}
className="closeElement"
>
X
</button>
<blockquote
type="text"
id="blogCode"
contentEditable="true"
className="codehighlight"
placeholder="Enter your code here"
{...register("blogCode", {
required: true
})}
value={code.value || ""}
onInput={(e) => handleChangeCode(idx, e)}
/>
</div>
);
})}
</div>
<div className="row">
</div>
<div className="row">
<div className="submitSection">
<input type="submit" className="submitBtn" />
</div>
</div>
</div>
</div>
</div>
<div className="blogListSection">
<h1>Edit blogs</h1>
<div className="row">
<div className="editBlogSection">
{blogList.map(({ id, heading, count }) => (
<a
key={id}
href="https://www.testingsite.com/"
className="blogitems"
>
<pre>
<span>{count}</span> {heading}
</pre>
</a>
))}
</div>
</div>
</div>
</div>
</div>
);
};
export default Admin;
react is designed for components . each of your list elements should be refactored by a component.then it would be easier. i think a single react component could do the trick

Submit and close modal window. React React-Hook-Form Typescript

I want to submit and close with the button "save". change type to "button" type="submit" value="submit" onClick={ onClose } don't submit and don't close. I am using onClose for close the modal
import { useAppDispatch } from '../redux/hooks';
import { userInfo } from '../redux/model';
import { useForm } from 'react-hook-form';
import { ModalProps } from '../redux/model';
import { setList } from '../redux/slice';
type UI = userInfo;
const AddData: React.FC<ModalProps> = ({ isOpen, onClose }) => {
const [ page, setPage ] = useState(0);
const FormTitles = ["Invoice Address", "Bank Data", "Contact"];
const dispatch = useAppDispatch();
const { register, handleSubmit, formState: { errors, isValid }} = useForm<UI>({ mode: "all" });
const onSubmit = handleSubmit((data) => {
dispatch(setList(data));
});
return isOpen ? (<div className="viewModal">
<div className='modalContent'>
<form onSubmit={ onSubmit }>
<div className="contentForm">
<div className="closeX" onClick={ onClose }>x</div>
<div className="labels">
<div className="titleTxt">{ FormTitles[page] }</div>
{ page === 0 && (<>
<div className="labelInput">
<label htmlFor="additional">Additional</label>
<input { ...register("additional")} id="additional" />
</div>
<div className="labelInput">
... // content
</div>
<div className="labelInput">
... // content
</div>
</>)}
{ page === 1 && (<>
<div className="labelInput">
<label htmlFor="iban">IBAN</label>
<div className="dirCol">
<input { ...register("iban", { required: true, maxLength: 30 })} id="iban" />
<div className="required">{ errors.iban && "This is required!" }</div>
</div>
</div>
<div className="labelInput">
... // content
</div>
{ page === 2 && (<>
{/* *** fax *** */}
<div className="labelInput">
<label htmlFor="fax">Fax</label>
<input { ...register("fax")} id="fax" />
</div>
<div className="labelInput">
... // content
</div>
<div className="labelInput">
... // content
</div>
</div>
<div className="labelButton">
<button className="button2" onClick={ onClose }>Cancel</button>
{ page !== 0 && (<div className="button2 textCancel" onClick={() => { setPage((x) => x - 1)}}
>Previous</div>)}
{ page !== 2 && (<button className="button1" type="button" disabled={ !isValid } onClick={() => { setPage((x) => x + 1)}}
>Next</button>)}
{ page === 2 && (<>
<button className="button1" type="submit" value="submit" onClick={ onClose }>Save</button>
</>)}
</div>
</div>
</form>
</div>
</div>) : null
};
export default AddData;
here AddData off and on, onClose working with cancel and x button
import { useState } from 'react';
import AddData from './AddData';
import { useAppDispatch, useAppSelector } from '../redux/hooks';
import { removeList } from '../redux/slice';
const ListTable = () => {
const [ isModalOpen, setIsModalOpen ] = useState(false);
const toogleModal = () =>setIsModalOpen(!isModalOpen);
const dispatch = useAppDispatch();
const selector = useAppSelector((state) => state.users.list );
return <>
<AddData isOpen={ isModalOpen } onClose={ toogleModal }>
</AddData>
<nav>
<button onClick={ toogleModal }>Add</button>
</nav>
<div className='content'>
... // content
</div>
</>
};
export default ListTable;
Inside of the onClick for your save button you can call onSubmit and onClose.
import { useAppDispatch } from "../redux/hooks";
import { userInfo } from "../redux/model";
import { useForm } from "react-hook-form";
import { ModalProps } from "../redux/model";
import { setList } from "../redux/slice";
type UI = userInfo;
const AddData: React.FC<ModalProps> = ({ isOpen, onClose }) => {
const [page, setPage] = useState(0);
const FormTitles = ["Invoice Address", "Bank Data", "Contact"];
const dispatch = useAppDispatch();
const {
register,
handleSubmit,
formState: { errors, isValid },
} = useForm<UI>({ mode: "all" });
const onSubmit = handleSubmit((data) => {
dispatch(setList(data));
});
return isOpen ? (
<div className="viewModal">
<div className="modalContent">
<form onSubmit={onSubmit}>
<div className="contentForm">
<div className="closeX" onClick={onClose}>
x
</div>
<div className="labels">
<div className="titleTxt">{FormTitles[page]}</div>
{page === 0 && (
<>
<div className="labelInput">
<label htmlFor="additional">Additional</label>
<input {...register("additional")} id="additional" />
</div>
<div className="labelInput">{/* ... // content */}</div>
<div className="labelInput">{/* ... // content */}</div>
</>
)}
{page === 1 && (
<>
<div className="labelInput">
<label htmlFor="iban">IBAN</label>
<div className="dirCol">
<input
{...register("iban", { required: true, maxLength: 30 })}
id="iban"
/>
<div className="required">
{errors.iban && "This is required!"}
</div>
</div>
</div>
<div className="labelInput">... // content</div>
</>
)}
{page === 2 && (
<>
{/* *** fax *** */}
<div className="labelInput">
<label htmlFor="fax">Fax</label>
<input {...register("fax")} id="fax" />
</div>
<div className="labelInput">{/* ... // content */}</div>
<div className="labelInput">{/* ... // content */}</div>
</>
)}
</div>
<div className="labelButton">
<button className="button2" onClick={onClose}>
Cancel
</button>
{page !== 0 && (
<div
className="button2 textCancel"
onClick={() => {
setPage((x) => x - 1);
}}
>
Previous
</div>
)}
{page !== 2 && (
<button
className="button1"
type="button"
disabled={!isValid}
onClick={() => {
setPage((x) => x + 1);
}}
>
Next
</button>
)}
{page === 2 && (
<>
<button
className="button1"
type="submit"
value="submit"
onClick={() => {
onSubmit();
onClose;
}}
>
Save
</button>
</>
)}
</div>
</div>
</form>
</div>
</div>
) : null;
};
export default AddData;

Opening all modals of a table at once react typescript

In an object array table, made by map, I need a delete modal, the problem is that when I click to open a single modal they all open from all the rows of the table as if I had clicked on all the buttons in the table not letting me select the right modal, I can't use this because of how I'm assembling the component. (I summarized the code but involving the button has a map running)
const TableAppointments = () => {
const [modalOpened, setModalOpened] = useState(false);
const [tableValues, setTableValues] = useState(tableAppointmentsMock);
const tasks = tableValues;
const setField = (newValue: any) => {
setTableValues((oldFormData: any) => ({ ...oldFormData, ...newValue }));
};
const handleDeleteTask = (id: any) => {
let arr = tableValues.filter((value) => {
return value.project.includes(id);
});
console.log(arr);
};
return (
<div className="gridContainer">
{tasks.length > 0 ? (
<div className="sectionContainer">
<section className="headerContent">
<div className="header headerProject">Projeto</div>
<div className="header headerTask">Tarefa</div>
<div className="header headerStart">Início</div>
<div className="header headerEnd">Fim</div>
<div className="header headertotal">Total</div>
<div className="header headerBlank"></div>
</section>
{tasks.map((task, index) => {
return (
<section className="taskContainer" key={task.id}>
<div className="tagContent">
<p className="tagClient">Cliente</p>
</div>
<input
className="task taskDescription"
placeholder="Insira uma tarefa"
value={task.tasks}
name="task"
// onBlur={handleChangeInput}
onChange={(e: any) => setField({ tasks: e.target.value })}
/>
<input
className="task startTask timer"
placeholder="--:--"
value={task.startTime}
name="start"
// onBlur={handleChangeInput}
onChange={(e: any) => setField({ startTime: e.target.value })}
/>
<input
className="task endTask timer"
placeholder="--:--"
value={task.stopTime}
name="stop"
// onBlur={handleChangeInput}
onChange={(e: any) => setField({ stopTime: e.target.value })}
/>
<input
className="task totalTask timer"
placeholder="--:--"
value={task.totalTime}
name="total"
// onBlur={handleChangeInput}
onChange={(e: any) => setField({ totalTime: e.target.value })}
/>
<section className="task taskIcons">
<button
className="btIcon"
onClick={() => {
setModalOpened(true);
}}
>
excluir
</button>
{modalOpened && (
<ModalDelete
id={task.id}
onClick={() => handleDeleteTask(task.project)}
onClose={() => setModalOpened(false)}
/>
)}
</section>
</section>
);
})}
</div>
) : (
<div className="noAppointments">
<p className="noAppointmentsText">
Você não possui apontamentos nesse dia, aponte suas horas clicando
no botão "Novo Apontamento"
</p>
</div>
)}
</div>
);
};

Cannot receive to get clicked button value in React.js

I tried to get the button value when I click the button (onClick method).
I tried to do generally the way that is e.target.value but sometimes it returns an undefined or empty string. Even I tried to arrow function way that I find in here but still doesn't work. Could you help me with this problem? Which part is wrong or do I miss something?
This is the main part of my code:
updateProducts = e => {
// e.preventDefault();
let buttonValue = e.target.value;
console.log(buttonValue);
fetch('/data/MainProductsShoes.json', {})
.then(res => res.json())
.then(data => {
this.setState({
productsInfo: data,
// category_id: '',
});
});
};
and
<main className="contentsBody">
<div className="contentsLink">
<div className="viewAll">
<button onClick={this.updateProducts} value="viewAll">
<span>전체보기</span>
</button>
</div>
<div className="Shoes">
<button onClick={this.updateProducts} value="shoes">
<span>신발</span>
</button>
</div>
<div className="Clothes">
<button onClick={this.updateProducts} title="clothing">
<span>의류</span>
</button>
</div>
<div className="Supplies">
<button onClick={this.updateProducts} title="acc">
<span>용품</span>
</button>
</div>
</div>
Here's the complete code:
import React, { Component } from 'react';
import './Main.scss';
import COLOR_LISTS from './colorList';
import Products from './ProductsInfo/Products';
export class Main extends Component {
constructor() {
super();
this.state = {
productsInfo: [],
};
}
// const API = "DASDDADDAD" => 컴포넌트 마다 다 적용할수x
componentDidMount() {
fetch('/data/MainProducts.json', {})
.then(res => res.json())
.then(data => {
this.setState({
productsInfo: data,
});
});
}
updateProducts = e => {
// e.preventDefault();
let buttonValue = e.target.value;
console.log(buttonValue);
fetch('/data/MainProductsShoes.json', {})
.then(res => res.json())
.then(data => {
this.setState({
productsInfo: data,
// category_id: '',
});
});
};
// updateProducts = () => {
// console.log('clicked');
// fetch('/data/MainProducts.json', {
// method: 'GET',
// })
// .then(res => res.json())
// .then(data => {
// this.setState({
// productsInfo: data,
// category_id: this.state.category_id,
// });
// });
// };
// showToProductDetailPage = () => {
// const { productsInfo } = this.state;
// productsInfo &&
// productsInfo.map((product, idx) => (
// <Products key={idx} productInfo={product} />
// ));
// };
render() {
const { productsInfo } = this.state;
return (
<div className="MainWrapper">
<div className="sectionHeader">
<div className="sectionTitle">
<div className="sectionTitleCategory">
<span className="categoryName">Men</span>
<br />
<br />
<span>Men's 의류(12)</span>
</div>
<div className="sectionControl">
<button>필터</button>
<select name="list" className="productsFilter">
<option value="newestOrdeer">신상품순</option>
<option value="hightCostoOder">높은가격순</option>
<option value="lowCostOrder">낮은가격순</option>
</select>
</div>
</div>
</div>
<div className="contentsWrapper">
<aside className="contentsSide">
<div className="HorizontalLine" />
<div className="colors">
<span>색상</span>
<ul className="colorLists">
{COLOR_LISTS.map((color, idx) => {
return (
<li className="colorLayout" title="베이지" key={idx}>
<input type="checkbox" />
<label
className="checkboxLabel"
for="checkbox"
style={{ backgroundColor: color.colorProps }}
/>
<span className="productColor">{color.color_name}</span>
</li>
);
})}
</ul>
</div>
<div className="sizes">
<div className="HorizontalLine" />
<span>사이즈</span>
<div className="sizeLists">
<button title="230">230</button>
<button title="230">235</button>
<button title="230">240</button>
<button title="230">245</button>
<button title="230">250</button>
<button title="230">255</button>
<button title="230">260</button>
<button title="230">265</button>
<button title="230">270</button>
<button title="230">275</button>
<button title="230">280</button>
</div>
<div className="HorizontalLine" />
</div>
</aside>
<main className="contentsBody">
<div className="contentsLink">
<div className="viewAll">
<button onClick={this.updateProducts} value="viewAll">
<span>전체보기</span>
</button>
</div>
<div className="Shoes">
<button onClick={this.updateProducts} value="shoes">
<span>신발</span>
</button>
</div>
<div className="Clothes">
<button onClick={this.updateProducts} title="clothing">
<span>의류</span>
</button>
</div>
<div className="Supplies">
<button onClick={this.updateProducts} title="acc">
<span>용품</span>
</button>
</div>
</div>
<article className="productsMapping">
{productsInfo &&
productsInfo.map((product, idx) => (
<Products key={idx} productInfo={product} />
))}
</article>
</main>
</div>
</div>
);
}
}
export default Main;
change you updateProducts function to receive a string value representing the product name:
updateProducts = (name) => {
console.log(name);
fetch('/data/MainProductsShoes.json', {})
.then(res => res.json())
.then(data => {
this.setState({
productsInfo: data,
// category_id: '',
});
});
};
Then on each button pass the product name as an argument:
<button onClick={() => this.updateProducts('shoes')}>
Use event.currentTarget.value instead of event.target.value.
let buttonValue = e.currentTarget.value;
console.log(buttonValue);
event.target points to the element where the click event triggered. In your case that can be either span inside the button sometimes and that is when you get undefined value.
event.currentTarget points to the element where the event handler is attached which is the button.
I also notice some of the buttons have title property instead of value property.
<div className="viewAll">
<button onClick={this.updateProducts} value="viewAll">
<span>전체보기</span>
</button>
</div>
<div className="Shoes">
<button onClick={this.updateProducts} value="shoes">
<span>신발</span>
</button>
</div>
<div className="Clothes">
<button onClick={this.updateProducts} title="clothing">
<span>의류</span>
</button>
</div>
<div className="Supplies">
<button onClick={this.updateProducts} title="acc">
<span>용품</span>
</button>
</div>

Why am I receiving 'Invalid hook call' error?

I am dispatching a redux action on a button click. When the button is clicked I then receive the error 'Invalid hook call. Hooks can only be called inside of the body of a function component.' I can have this same action be dispatched on the page render and it works fine. I have other actions being dispatched onClick but this one isn't working.
This is the action
import axios from "axios";
export const addReview = (productInfo) => async (dispatch) => {
try {
await axios({
method: "post",
url: url,
header: { "Content-Type": "application/json" },
data: {
name: productInfo.name,
rating: productInfo.rating,
description: productInfo.description,
buyAgain: productInfo.buyAgain,
productId: productInfo.productId,
},
}).then((response) => {
dispatch({
type: "PRODUCTS_SUCCESS",
payload: response.data,
});
});
} catch (error) {
dispatch({
type: "PRODUCTS_FAILURE",
payload: error,
});
}
};
And here is the action dispatch on onClick event
const submitReview = () => {
let productInfo = {
name,
rating: starRate,
description: message,
buyAgain,
productId: currentProduct,
};
dispatch(addReview(productInfo));
};
Here is the entire component
import React, { useState } from "react";
import { useSelector, useDispatch } from "react-redux";
import "./ProductReview.css";
import { ImStarEmpty } from "react-icons/im";
import { ImStarFull } from "react-icons/im";
import { IoPersonCircle } from "react-icons/io5";
import { addReview } from "../../actions/addReview";
export const ProductReview = () => {
const [starRate, setStarRate] = useState();
const [message, setMessage] = useState();
const [buyAgain, setBuyAgain] = useState(true);
const [missingRating, setMissingRating] = useState(false);
const dispatch = useDispatch();
const fName = localStorage.getItem("firstName");
const currentProduct = useSelector(
(state) => state.userInfoReducer.currentProductReview
);
const allProducts = useSelector((state) => state.productReducer.data);
let productToDisplay;
let title;
let name;
allProducts.map((product) => {
if (product._id === currentProduct) {
productToDisplay = product;
if (product.title.length > 60) {
title = product.title.substring(0, 60) + "...";
}
}
return productToDisplay;
});
const submitReview = () => {
let productInfo = {
name,
rating: starRate,
description: message,
buyAgain,
productId: currentProduct,
};
dispatch(addReview(productInfo));
};
return (
<>
<div className="product-review-container">
<h1 className="product-review-title">Create Review</h1>
<div className="product-review-product">
<img
className="review-product-img"
src={productToDisplay.image}
alt="product"
/>
<h2 className="review-product-title">{title}</h2>
</div>
<hr className="line-break" />
<div className="review-product-review">
<div className="review-product-review-container">
<h2 className="review-product-review-title">Overall Rating</h2>
<p className="review-product-review-stars">
{starRate >= 1 ? (
<ImStarFull
className="star-full"
onClick={() => setStarRate(1)}
/>
) : (
<ImStarEmpty
className="star-empty"
onClick={() => setStarRate(1)}
/>
)}
{starRate >= 2 ? (
<ImStarFull
className="star-full"
onClick={() => setStarRate(2)}
/>
) : (
<ImStarEmpty
className="star-empty"
onClick={() => setStarRate(2)}
/>
)}
{starRate >= 3 ? (
<ImStarFull
className="star-full"
onClick={() => setStarRate(3)}
/>
) : (
<ImStarEmpty
className="star-empty"
onClick={() => setStarRate(3)}
/>
)}
{starRate >= 4 ? (
<ImStarFull
className="star-full"
onClick={() => setStarRate(4)}
/>
) : (
<ImStarEmpty
className="star-empty"
onClick={() => setStarRate(4)}
/>
)}
{starRate >= 5 ? (
<ImStarFull
className="star-full"
onClick={() => setStarRate(5)}
/>
) : (
<ImStarEmpty
className="star-empty"
onClick={() => setStarRate(5)}
/>
)}
</p>
{missingRating ? (
<p className="missing-rating">! Must choose a rating</p>
) : (
""
)}
</div>
<button
className="review-product-review-clear"
onClick={() => setStarRate(0)}
>
Clear
</button>
</div>
<div className="review-product-buy-again">
<h2 className="review-product-buy-again-title">
Would you buy this item again?
</h2>
<div className="btn-group btn-group-toggle" data-toggle="buttons">
<label className="btn btn-secondary active">
<input
type="radio"
name="options"
id="option1"
autoComplete="off"
onClick={() => setBuyAgain(true)}
/>{" "}
Yes
</label>
<label className="btn btn-secondary">
<input
type="radio"
name="options"
id="option2"
autoComplete="off"
onClick={() => setBuyAgain(false)}
/>{" "}
No
</label>
</div>
</div>
<hr className="line-break" />
<div className="review-product-message">
<h2 className="review-product-message-title">
Add a written message
</h2>
<input
type="text"
className="form-control review-product-message-input"
placeholder="What did you like or dislike?"
onChange={(e) => setMessage(e.target.value)}
/>
<h2 className="review-product-name-title">Choose your public name</h2>
<p className="review-product-appear">
This is how you'll appear to other customers
</p>
<div className="review-product-user-info">
<IoPersonCircle className="review-product-profile" />
<input
type="text"
className="form-control review-product-profile-name"
defaultValue={fName}
onChange={(e) => (name = e.target.value)}
/>
</div>
<hr className="line-break" />
<button
className="review-product-submit"
onClick={() => submitReview()}
>
Submit
</button>
{missingRating ? (
<p className="missing-rating">Missing information</p>
) : (
""
)}
</div>
</div>
</>
);
};
Out of sync versions of React and React DOM
You can run npm ls react-dom in your react projet and if the version is less then 16.8.0 it does not yet support Hooks
2- Do not call Hooks in event handlers.
Your hooks must always be at the top of your functional Component. You may be able to resolve this by simply moving down the initialization of ‘fName’ below your hooks.

Resources