I'm a beginner creating a basic calculator app, expanding on a tutorial I followed. I'd like to add functionality to accept keyboard input in addition to the onClick events. I've tried the methods used in the docs, but it ends up duplicating the last clicked value instead of inputting the correct value. Here's my app:
import { useState } from "react"
function App() {
const [calc, setCalc] = useState("")
const [result, setResult] = useState("")
const ops = ['/', '*', '+', '-', '.']
const updateCalc = value => {
if (
(ops.includes(value) && calc === "") ||
(ops.includes(value) && ops.includes(calc.slice(-1)))
) {
setCalc(calc.slice(0,-1) + value)
return;
}
setCalc(calc + value)
if (!ops.includes(value)) {
setResult(eval(calc + value).toString());
}
}
const createDigits = () => {
const digits = []
for (let i = 1; i < 10; i++) {
digits.push(
<input type="button"
onClick={() => updateCalc(i.toString())} key={i}
onKeyPress={() => updateCalc(i.toString())}
value={i} />
)
}
return digits
}
const calculate = () => {
setCalc(eval(calc).toString())
setResult("")
}
const deleteLast = () => {
if (calc === "") {
return;
}
const value = calc.slice(0, -1);
setCalc(value)
}
return (
<div className="App">
<div className="calculator">
<div className="display">
{result ? <span>({result})</span> : ""}
{ calc || "0"}
</div>
<div className="operators">
<input type="button" onClick={() => updateCalc("/")} value="/" />
<input type="button" onClick={() => updateCalc("*")} value="*" />
<input type="button" onClick={() => updateCalc("+")} value="+" />
<input type="button" onClick={() => updateCalc("-")} value="-" />
<input type="button" onClick={deleteLast} value="DEL" />
</div>
<div className="digits">
{ createDigits() }
<input type="button" onClick={() => updateCalc("0")} value="0" />
<input type="button" onClick={() => updateCalc(".")} value="." />
<input type="button" onClick={calculate} value="=" />
</div>
</div>
</div>
);
}
export default App;
You can achieve this with the concept of useEffect and watch for the keydown event. If the key is pressed you can check the value and call updateCalc function in handleKeyPress:
// handle what happens on key press
const handleKeyPress = useCallback((event) => {
// Call updateCalc here
console.log(`Key pressed: ${event.key}`);
}, []);
useEffect(() => {
// attach the event listener
document.addEventListener('keydown', handleKeyPress);
// remove the event listener
return () => {
document.removeEventListener('keydown', handleKeyPress);
};
}, [handleKeyPress]);
Related
When editing a todo it will automictically clear the value, I would like it to contain its original value so you can edit upon it rather than typing everything all over again.
Im assuming usestate is setting the editingText into an empty string in which case in will always output a empty value?
Also I would like to incorporate a cancel button in which cancels eiditing and returns back to its current value.
const App = () => {
const [todos, setTodos] = React.useState([]);
const [todo, setTodo] = React.useState("");
const [todoEditing, setTodoEditing] = React.useState(null);
const [editingText, setEditingText] = React.useState("");
function handleSubmit(e) {
e.preventDefault();
const newTodo = {
id: new Date().getTime(),
text: todo,
completed: false,
};
setTodos([...todos].concat(newTodo));
setTodo("");
}
function deleteTodo(id) {
let updatedTodos = [...todos].filter((todo) => todo.id !== id);
setTodos(updatedTodos);
}
function toggleComplete(id) {
let updatedTodos = [...todos].map((todo) => {
if (todo.id === id) {
todo.completed = !todo.completed;
}
return todo;
});
setTodos(updatedTodos);
}
function submitEdits(id) {
const updatedTodos = [...todos].map((todo) => {
if (todo.id === id) {
todo.text = editingText;
}
return todo;
});
setTodos(updatedTodos);
setTodoEditing(null);
}
return (
<div id="todo-list">
<h1>Todo List</h1>
<form onSubmit={handleSubmit}>
<input
type="text"
onChange={(e) => setTodo(e.target.value)}
value={todo}
/>
<button type="submit">Add Todo</button>
</form>
{todos.map((todo) => (
<div key={todo.id} className="todo">
<div className="todo-text">
{todo.id === todoEditing ? (
<input
type="text"
onChange={(e) => setEditingText(e.target.value)}
/>
) : (
<div>{todo.text}</div>
)}
</div>
<div className="todo-actions">
{todo.id === todoEditing ? (
<button onClick={() => submitEdits(todo.id)}>Submit Edits</button>
) : (
<button onClick={() => setTodoEditing(todo.id)}>Edit</button>
)}
<button onClick={() => deleteTodo(todo.id)}>Delete</button>
</div>
</div>
))}
</div>
);
};
export default App;
Use defaultValue to set the initial value of the input
<div className="todo-text">
{todo.id === todoEditing ? (
<input
defaultValue={todo.text}
type="text"
onChange={(e) => setEditingText(e.target.value)}
/>
) : (
<div>{todo.text}</div>
)}
</div>
Adding a cancel button is just setting your edit id to null
<>
<button onClick={() => submitEdits(todo.id)}>
Submit Edits
</button>
<button onClick={() => setTodoEditing(null)}>Cancel</button>
</>
Stackblitz: https://stackblitz.com/edit/react-ts-rarpqn?file=App.tsx
Use value prop
{todo.id === todoEditing ? (
<input
value={todo.text}
type="text"
onChange={(e) => setEditingText(e.target.value)}
/>
) : (
<div>{todo.text}</div>
)}
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)
}
There is a component:
import React, { useEffect, useState } from "react";
import { useParams } from "react-router";
import { NavLink } from "react-router-dom";
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(true);
const [errorEmailEmpty, isErrorEmailEmpty] = useState(true);
const [errorEmailValid, iserrorEmailValid] = useState(false);
const [errorStartEmpty, isErrorStartEmpty] = useState(true);
const [errorEndEmpty, isErrorEndEmpty] = useState(true);
const validEmail = new RegExp(
/(\w+([-+.']\w+)*#\w+([-.]\w+)*\.\w+([-.]\w+)*)/gm
);
const dateValidate = () => {
if (start.value > end.value) {
console.log("Start > end");
console.log(start.valueAsNumber);
console.log(end.valueAsNumber);
} else {
console.log("Ok");
console.log(start.valueAsNumber);
console.log(end.valueAsNumber);
}
};
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>
<NavLink to="/">Back to list </NavLink>
<form>
<label>Name</label>
<input
type="text"
name="name"
value={name}
onChange={(e) => {
if (e.target.value === "") {
isErrorNameEmpty(true);
} else {
isErrorNameEmpty(false);
}
inputName(e.target.value);
}}
onClick={(e) => {
if (e.target.value === "") {
isErrorNameEmpty(true);
}
}}
/>
{errorNameEmpty ? <span>Name can't be empty</span> : <></>}
<label>Email</label>
<input
type="text"
name="email"
value={email}
onChange={(e) => {
if (e.target.value === "") {
isErrorEmailEmpty(true);
} else if (!validEmail.test(e.target.value)) {
iserrorEmailValid(true);
isErrorEmailEmpty(false);
} else {
iserrorEmailValid(false);
isErrorEmailEmpty(false);
}
inputEmail(e.target.value);
}}
onClick={(e) => {
if (e.target.value === "") {
isErrorEmailEmpty(true);
}
}}
/>
{errorEmailEmpty ? <span>Email can't be empty</span> : <></>}
{errorEmailValid ? <span>Example: email#gmail.com</span> : <></>}
<label>Start date</label>
<input
type="date"
name="email"
value={start}
onChange={(e) => {
if (e.target.value === "") {
isErrorStartEmpty(true);
} else {
isErrorStartEmpty(false);
}
inputStart(e.target.value);
}}
onClick={(e) => {
if (e.target.value === "") {
isErrorStartEmpty(true);
}
}}
/>
{errorStartEmpty ? <span>Start date can't be empty</span> : <></>}
<label>End date</label>
<input
type="date"
name="email"
value={end}
onChange={(e) => {
inputEnd(e.target.value);
if (e.target.value === "") {
isErrorEndEmpty(true);
} else {
isErrorEndEmpty(false);
}
dateValidate();
}}
onClick={(e) => {
if (e.target.value === "") {
isErrorEndEmpty(true);
}
}}
/>
{errorEndEmpty ? <span>End date can't be empty</span> : <></>}
<input type="submit" value="Submit" />
</form>
<h2>{intern.name}</h2>
<h2>{intern.email}</h2>
<h2>{intern.internshipStart}</h2>
<h2>{intern.internshipEnd}</h2>
</div>
);
};
export default EditIntern;
It has two inputs of type date. The task is to check that the start date is not greater than the end date.
I created a dateValidate function for this (which doesn't work as it should).
How can you solve this problem? (Perhaps my approach to form validation is generally not correct, I’ll be happy to read about my mistakes)
transform start date and end date to milliseconds new Date(start date).getTime() than compare it (>, <, >=) to the end date also transformed into milliseconds
first select right property
// inputEnd(e.target.value);
if (!isNaN(e.target.valueAsNumber)) inputStart(e.target.valueAsNumber);
// ...
//...
// inputEnd(e.target.value);
if (!isNaN(e.target.valueAsNumber)) inputEnd(e.target.valueAsNumber);
then validate
// ..when user submits start validation
const onFormSubmit = (e) => {
e.preventDefault()
// ...
if (start < end) {
// blah blah....
}
}
or better add min and max value so you dont have to check all
<input type="date" name="start" min="2017-01-01" max="2022-01-01">
also please dont use onChage with onClick event listeners its very bad practice
use either one of them, in this case onChage is pretty good.
seems use are using onClick for validating, use useEffect for validating and keep separate state for errors (object).
and check more options here MDN docs and play around with devtools (right click on element, select use in console option and see what properties it holds)
I'm new to React and try to make a simple crud with Springboot.
at certain point I need to use a ternary operator, but it doesn't work. I used it before in React with no problem, I don't understand why now is not working.
So I used a function and is working, except when I have to empty a div, which gave me a problem and need to use jquery. So now the code is working, I just would like to know what I'm doing wrong in the ternary and in emptying the div with javascript.
I will post the full working code, then just the piece of code that would like to use vs the code that is actually working.
Thanks for your patience
import { React, useState, useEffect } from "react";
import { useHistory } from "react-router";
import ServiceUtente from "../service/ServiceUtente";
import $ from "jquery";
const Utente = () => {
const history = useHistory();
const [utenti, setUtenti] = useState([]);
const [isDeleted, setIsDeleted] = useState(false);
const [searchBy, setSearchBy] = useState("");
let checkedNome = false;
let checkedEmail = false;
let checkedProfilo = false;
useEffect(() => {
retrieveUtenti();
}, [isDeleted]);
// retrieve data from db and store it into utenti
const retrieveUtenti = () => {
ServiceUtente.utenteGetAll()
.then((response) => {
setUtenti(response.data);
})
.catch((e) => {
console.log(e);
});
};
const viewUtente = (id) => {
history.push(`/view-utente/${id}`);
};
const aggiungiUtente = () => {
history.push("/aggiungi-update-utente/_add");
};
const deleteUtente = (id) => {
ServiceUtente.utenteDelete(id)
.then((response) => {
setIsDeleted(!isDeleted);
})
.catch((e) => {
console.log(e);
});
};
const updateUtente = (id) => {
history.push(`/aggiungi-update-utente/${id}`);
};
const handleSearch = (e) => {
setSearchBy(e.target.value);
};
const handleNome = (e) => {
checkedNome = e.target.checked;
console.log("nome: " + checkedNome);
nomeForm();
};
const handleEmail = (e) => {
checkedEmail = e.target.checked;
console.log("email: " + checkedEmail);
};
const handleProfilo = (e) => {
checkedProfilo = e.target.checked;
console.log("profilo: " + checkedProfilo);
};
const formSearchBy = () => {
// console.log("");
};
const nomeForm = () => {
if (checkedNome === true) {
document.getElementById("nomeForm").innerHTML = `
<input
type="text"
className="form-control"
placeholder="Search Utente"
value="${searchBy}"
onChange="${handleSearch}"
/>`;
} else {
// document.getElementById("nomeForm").innerHTML = "";
$("#nomeForm").empty();
}
};
return (
<div className="row">
<div className="col-sm-10 offset-1">
<h2 className="login-title my-4" style={{ textAlign: "center" }}>
GM Utente
</h2>
{/* ***********************SEARCH BAR****************************************** */}
<form onClick={formSearchBy}>
<h4 style={{ textAlign: "center" }}>
Spuntare i campi desiderati per la ricerca
</h4>
<div className="form-check">
<input
onChange={handleNome}
className="form-check-input"
type="checkbox"
name="nomeCheck"
value=""
id="nomeUtente"
/>
<label className="form-check-label" htmlFor="nomeUtente">
Nome Utente
</label>
<div id="nomeForm">{nomeForm()}</div>
</div>
<div
className="input-group-append my-2 text-center"
style={{ textAlign: "center" }}
>
<button
className="btn btn-success"
type="submit"
id="button-addon2"
>
Search
</button>
</div>
</form>
{/* ***********************END SEARCH BAR*********************************** */}
<button
type="button"
className="btn btn-primary my-2"
onClick={() => aggiungiUtente()}
>
Aggiungi Utente
</button>
<table
className="table table-striped table-bordered"
style={{ textAlign: "center" }}
>
<thead>
<tr>
<th>Id Utente</th>
<th>Nome Utente</th>
<th>Email</th>
<th>Password</th>
<th>Profilo Utente</th>
<th>Azioni</th>
</tr>
</thead>
<tbody>
{utenti.map((utente) => (
<tr key={utente.idUtente}>
<td>{utente.idUtente}</td>
<td>{utente.nomeUtente}</td>
<td>{utente.email}</td>
<td>{utente.password}</td>
<td>{utente.profiloUtente.nomeProfilo}</td>
<td>
<button
onClick={() => viewUtente(utente.idUtente)}
type="button"
className="btn btn-secondary mx-1"
>
Details
</button>
<button
onClick={() => updateUtente(utente.idUtente)}
type="button"
className="btn btn-warning mx-1"
>
Update
</button>
<button
onClick={() => deleteUtente(utente.idUtente)}
type="button"
className="btn btn-danger mx-1"
>
Delete
</button>
</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
);
};
export default Utente;
All this code is working but I would like to use this
{checkedNome === true ? (
<input
type="text"
className="form-control"
placeholder="Search Utente"
value={searchBy}
onChange={handleSearch}
/>
) : null}
Instead of this function
const nomeForm = () => {
if (checkedNome === true) {
document.getElementById("nomeForm").innerHTML = `
<input
type="text"
className="form-control"
placeholder="Search Utente"
value="${searchBy}"
onChange="${handleSearch}"
/>`;
} else {
// document.getElementById("nomeForm").innerHTML = "";
$("#nomeForm").empty();
}
};
Also, in this function, why the Jquery syntax is working and the '.innerHTML = "";' commented out is not?
Thanks
Issue
The issue is that you aren't updating any state in order to trigger a render. checkedNome is declared in the function body and mutating it won't trigger React to do anything.
let checkedNome = false;
const handleNome = (e) => {
checkedNome = e.target.checked; // <-- mutation
console.log("nome: " + checkedNome);
nomeForm(); // <-- DOM mutation
};
Solution
Move the checkedNome into component state:
const [checkedNome, setCheckedNome] = React.useState(false);
Update handleNome to enqueue a state update:
const handleNome = (e) => {
const { checked } = e.target;
setCheckedNome(checked);
};
Update the render return to conditionally render the input:
<div id="nomeForm">
{checkedNome && (
<input
type="text"
className="form-control"
placeholder="Search Utente"
value={searchBy}
onChange={handleSearch}
/>
)}
</div>
Hello All I am new guy working with react hooks. In the code given below I am passing my function as props and onclick it should delete the selected the id but It is getting invoked without calling it.
Here is my code:
App.js
import React, { useState } from 'react';
import './App.css';
import Keypad from './components/Keypad';
import Result from './components/Result';
import Alerts from './components/Alerts';
import ShowTickets from './components/ShowTickets';
import uuid from 'uuid';
const uuidv4 = require('uuid/v4');
function App() {
const [result, setResult] = useState('');
const [tickets, setTickets] = useState([]);
const [showMessage, setShowMessage] = useState(false);
const [message, setMessage] = useState('');
const [count, setCount] = useState(1);
const deleteTicket = id => {
console.log(id + ' from delete');
const data = tickets.filter(ticket => ticket.id !== id);
setTickets(data);
};
const randomNumber = () => {
setResult(Math.floor(100000 + Math.random() * 900000));
};
const backSpace = () => {
if (result.length !== 0) {
setResult(result.substring(0, result.length - 1));
} else {
error('Enter some number to remove');
}
};
const cb = value => {
if (result.length <= 5) {
setResult(result + value);
} else {
error('Only 6 digit tickets are allowed');
}
};
const deleteAll = ()=>{
setResult('')
}
const error = message => {
setShowMessage(true);
setMessage(message);
setTimeout(() => {
setShowMessage(false);
setMessage('');
}, 3000);
};
const addTicket = () => {
if (result !== '') {
if (count <= 5) {
if (parseInt(result) < 100000 || parseInt(result) > 999999) {
error('Value should be between 100000 & 999999');
} else {
setCount(count + 1);
const ticket = { count: count, value: result, id: uuidv4() };
setTickets(tickets => [...tickets, ticket]);
}
} else {
error('Only 5 tickets allowed');
}
} else {
error('Set the ticket id before adding ticket');
}
};
return (
<div className='ta-center'>
<center>
{showMessage ? <Alerts message={message} /> : ''}
{result !== '' ? <Result result={result} /> : ''}
<Keypad cb={cb} backSpace={backSpace} />
<button className='width' name='add' onClick={addTicket}>
<i className='fa fa-plus'></i>Add Tickets
</button>
{tickets.length ? (
<ShowTickets tickets={tickets} deleteTicket={deleteTicket} />
) : (
'No tickets to show'
)}
</center>
</div>
);
}
export default App;
Keypad.js
import React from 'react';
const Keypad = ({ cb, backSpace, deleteAll}) => {
return (
<div className='button'>
<button name='7' onClick={e => cb(e.target.name)}>
7
</button>
<button name='8' onClick={e => cb(e.target.name)}>
8
</button>
<button name='9' onClick={e => cb(e.target.name)}>
9
</button>
<br />
<button name='4' onClick={e => cb(e.target.name)}>
4
</button>
<button name='5' onClick={e => cb(e.target.name)}>
5
</button>
<button name='6' onClick={e => cb(e.target.name)}>
6
</button>
<br />
<button name='1' onClick={e => cb(e.target.name)}>
1
</button>
<button name='2' onClick={e => cb(e.target.name)}>
2
</button>
<button name='3' onClick={e => cb(e.target.name)}>
3
</button>
<br />
<button name='C' onClick={e => backSpace()}>
<i className='fa fa-arrow-left'></i>
</button>
<button name='0' onClick={e => cb(e.target.name)}>
0
</button>
<button name='CE' onClick={e => deleteAll()}>
<i className='fa fa-trash'></i>
</button>
<br />
</div>
);
};
export default Keypad;
Result.js
import React from 'react';
const Result = ({ result }) => {
return (
<div>
{result.length === '' ? (
<small>
<div className='danger'>Enter 6 digits</div>
</small>
) : (
<h3>{result}</h3>
)}
</div>
);
};
export default Result;
Alerts.js
import React from 'react';
const Alerts = ({ message }) => {
return (
<div className='alert alert-danger'>
<strong>{message}</strong>
</div>
);
};
export default Alerts;
ShowTickets.js
import React from 'react';
const ShowTickets = ({ tickets, deleteTicket }) => {
const cb = id => {
deleteTicket(id);
};
return (
<div>
Your Selected Tickets are:
{Object.entries(tickets).map(([key, val]) => (
<h2 key={key}>
<button onClick={cb(val.id)}>
ticket #{parseInt(key) + 1} {val.value}
</button>
</h2>
))}
</div>
);
};
export default ShowTickets;
Onclicking the addticket I get id in console but no ticket is displayed. If I remove deletticket from there it works fine.
In your ShowTickets.js
<button onClick={cb(val.id)}>
you are calling handler not setting it.
I believe it should be
<button onClick={() => cb(val.id)}>