So Im going through React Course and I did exactly what I had to do but it seems that I cant execute preventDefault function on form submit and I dont really know why if anyone has any idea please let me know form keeps refreshing when submitted
import './ExpenseForm.css'
import { useState } from "react";
const ExpenseForm = () => {
const [enteredTitle, setEnteredTitle] = useState('');
const [enteredAmount, setEnteredAmount] = useState('6');
const [enteredDate, setEnteredDate] = useState('');
const titleChangeHandler = (event) => {
setEnteredTitle(event.target.value);
};
const amountChangeHandler = (event) => {
setEnteredAmount(event.target.value);
};
const dateChangeHandler = (event) => {
setEnteredDate(event.target.value);
};
//this is the funnction that handles Submit button
function submitHandler (event) {
event.preventDefault();
console.log("go")
const expenseData = {
title: enteredTitle,
amount: enteredAmount,
date: new Date(enteredDate)
}
};
return (
// this is the form and pointer to function that should execute when form is submitted
<form onSubmit={submitHandler}>
<div className="new-expense__controls">
<div className="new-expense__control">
<label>Title</label>
<input type="text" onChange={titleChangeHandler}/>
</div>
<div className="new-expense__control">
<label>Amount</label>
<input type="number" min="0.01" step="0.01" onChange={amountChangeHandler}/>
</div>
<div className="new-expense__control">
<label>Date</label>
<input type="date" min="2019-01-01" max="2022-12-31" onChange={dateChangeHandler}/>
</div>
</div>
<div className="new-expense__actions">
// this is the button that submits
<button type='submit'>Add Expense</button>
</div>
</form>
);
}
export default ExpenseForm;
I checked everything but I ant seem to solve problem at first I thought that I had syntax error but I didnt find anything...
Related
I have started an internship I have to build a to-do list using NEXT JS. but the problem arises that the app also updates an empty string. I have to work on this and have more than 20 hours to dig up a solution. I wasn't able to solve it. I tried passing some parameters but it's not working.
import { useState } from "react"
import '../styles/globals.css'
const index=()=> {
const [userinput,setuserinput]=useState("")
const [todolist,settodolist]=useState([])
const handlechange=(e)=>{
e.preventDefault()
if(e.target.value!=""){
setuserinput(e.target.value)
}
}
const handlesubmit=(e)=> {
settodolist([
userinput,
...todolist
])
e.preventDefault()
}
const handledelete=(todo)=>{
const updatedelete=todolist.filter(todoitem => todolist.indexOf(todoitem) != todolist.indexOf(todo))
settodolist(updatedelete)
}
return(
<div className="FLEX">
<h3 className="heading">Welcome to Next JS To Do app</h3>
<form className="FORM">
<div className="Wrap">
<input type="text" onChange={handlechange} placeholder="Enter a todo item" className="INPUT"></input>
<button onClick={handlesubmit} className="Button">Submit</button>
</div>
</form>
<ul>
{
todolist.length>=1?todolist.map((todo,idx)=>{
return <li key={idx}>{todo} <button onClick={(e)=>{
e.preventDefault()
handledelete(todo)
}}>Delete</button></li>
}):"Enter a Todo List"
}
</ul>
</div>
)
}
export default index
You need to pass the value prop to your input element:
<input type="text" value={userinput} onChange={handlechange} placeholder="Enter a todo item" className="INPUT"></input>
If you don't want the user to submit an empty item to the todo list, check if the userinput is empty or not.
const handlesubmit = (e) => {
if (userinput === "") return
settodolist([
userinput,
...todolist
])
e.preventDefault()
}
I believe the question is asking to prevent the user from entering a todo item with no name. In this case, do as the previous comment mentioned and add the value prop to the input:
<input type="text" value={userinput} onChange={handlechange} placeholder="Enter a todo item" className="INPUT"></input>
then add this to your handleSubmit function:
const handlesubmit = (e) => {
e.preventDefault();
if (userinput != '') {
settodolist([userinput, ...todolist]);
}
};
Hello Guys I am new in react JS , I got a Task , I which task I stuck , when I click on button Gifs is displayed but I Don't know how to select a particular Gif. Can anyone help me to Solve this Bugs.
If You Have any query please free feel to ask
App.js
I Used GIPHY API to displayed gifs. and Axiox for Fetching data
import "./App.css";
import { useEffect, useState } from "react";
import Axios from 'axios';
function App() {
const Api_key="XXX";
const Base_Url = "http://api.giphy.com/v1/gifs/search";
const [searchText,setSearchText] = useState("");
const [searchGif,setSearchGif] = useState("");
const [addText,setAddText] = useState([]);
const [gifs,setGifs] = useState([]);
const postValue = ()=>{
// Add Text
const addData = {
id:Date.now(),
name:searchText
}
console.log(addData);
setAddText([...addText,addData])
setSearchText("");
// Add Gifs
gifResponse();
}
const gifResponse = async()=>{
const response = await Axios.get(`${Base_Url}?api_key=${Api_key}&q=${searchGif}`)
// const res = await response.json();
setGifs(response.data.data);
console.log(response.data.data)
}
return (
<div className="App">
<div className="container">
<textarea
type="text"
className="textarea form-control shadow-none mt-3"
rows="15"
cols="45"
placeholder="Write Something Here..."
value={searchText}
onChange={(e)=>setSearchText(e.target.value)}
/>
<div class="input-group mb-3 mt-2">
<input
type="text"
class="form-control shadow-none inputtext"
placeholder="Search Gif..."
aria-label="Recipient's username"
aria-describedby="basic-addon2"
value={searchGif}
onChange={(e)=>setSearchGif(e.target.value)}
/>
<div class="input-group-append">
<span class="input-group-text " id="basic-addon2" onClick={postValue}>
POST & SEARCH
</span>
</div>
</div>
{
addText.map((add,index)=>{
return <h4 key={index}>{add.name}</h4>
})
}
{
gifs.map((gif)=>{
return <img src={gif.images.fixed_height.url} />
})
}
</div>
</div>
);
}
export default App;
You could add the URL of the gif to your postValue function.
First you'll need to create state for it:
const [selectedGif, setSelectedGif] = useState("");
In your Gif loop, add an onClick event to set the selected gif:
gifs.map((gif, index)=> <img src={gif.images.fixed_height.url} key={"gif-"+index} onClick={() => setSelectedGif(gif.images.fixed_height.url)} />)
Note that when you loop you should always include a key property at the root of the element you are creating.
Lastly, in your postValue function, add the selected gif:
const addData = {
id: Date.now(),
name: searchText,
gifUrl: selectedGif
}
I am working on a form in nextjs and i would love the data to remain the same i.e persist after the entire page as been refreshed or reloaded . Local storage doesnt work with next js , so i am looking for an alternative , i always get local storage not defined when i use it
Here is my code below
import React, { useState, useEffect, useLayoutEffect, createContext , useContext } from "react";
import { useRouter } from "next/router";
import Cookie from "js-cookie";
import { parseCookies } from "../helpers/index";
import { Formik } from "formik";
function Form() {
return (
<div>
<form action="" >
<section class="left">
<div class="input-container">
<label for="name">Full name</label>
<input type="text"/>
</div>
<div class="input-container">
<label for="age" required>
Mobile Number
</label>
<input type="text"/>
</div>
<div class="input-container">
<label for="phone">Choose password</label>
<input type="text"/>
</div>
</div>
</section>
</form>
</div>
);
}
export default Form;
With formik out of the question, to let data persist after refresh, you need to save it to localStorage ( or cookies ).
This works for NextJS (you need to test for window first)
Example as follows
const App = () => {
const [ value, setValue ] = useState({
name: '',
mobile: ''
});
useEffect(() => {
//you need to call this for nextjs, so this is performed only on client side.
if (typeof window !== 'undefined') {
let storedValue = localStorage.getItem('value');
if (storedValue) {
storedValue = JSON.parse(storedValue) || {}
// we explicitly get name and mobile value in case localStorage was manually modified.
const name = storedValue.name || ''
const mobile = storedValue.mobile || ''
setValue({ name, mobile }) //restore value from localStorage
}
}
},[])
// alternatively a betterway to handle side effect is useEffect
// useEffect(() => {
// localStorage.setItem('value', JSON.stringify(value))
// },[value])
const onChange = (e) => {
const name = e.target.name
const newValue = { ...value, [name]: e.target.value }
setValue(newValue);
localStorage.setItem('value', JSON.stringify(newValue)) //save input to localstorage
}
return (<div>
<input name="name" value={value.name} onChange={onChange} />
<input name="mobile" value={value.mobile} onChange={onChange} />
</div>
)
}
}
I am writing a simple react application, now I am working on an element that can take the user's input. I have been very curious about the order of the execution of line of code inside the onChange() function. So I added a little print statement to see how exactly things are changed.
Here's my code
function CreateReview() {
const [input, setInput] = useState({
title:'',
content:''
})
useEffect(() => {
console.log('render');
},[input])
function handleChange(event){
const {name, value} =event.target;
console.log(1)
setInput(prevInput=>
{
console.log(2)
return{
...prevInput, //...prevInput is to reserve the last Input
[name]: value //name is dynamic, "title" then setTitle, "content" then setContent.
}
}
)
console.log(3)
console.log(event.target);
}
function handleClick(event){
event.preventDefault();
console.log(input);
}
return <div className = "container">
<h1>Create Review</h1>
<form>
<div className="form-group">
<input onChange={handleChange} name="title" value={input.title} autoComplete="off" className = 'form-control' placeholder="Your Name"></input>
</div>
<div className="form-group">
<textarea onChange={handleChange} name="content" value={input.content} autoComplete="off" className = 'form-control' placeholder="Review Content"></textarea>
</div>
<button onClick={handleClick} className="btn btn-large btn-info">Add Note</button>
</form>
</div>
}
export default CreateReview;
And here's the output console
Console screenshot
I wonder why it goes 1,3,2. is there any reason behind it?
Kindly go to react document to read more about how state works in react.
As far as your concerned useState or setState are the async events, so whenever you are try to call them it will execute later rather do synchronously(line by line).
I am following the Scrimba tutorial on React but I decided to move my Form to a new file/component and change the functions to ES6.
Can someone tell me why? Thanks!
Now the handle Submit is not working (it works when the form is rendered in Meme Generator) but I don't know why and it doesn't throw any errors.
import React, { Component } from 'react'
import Form from "./Form"
class MemeGenerator extends Component {
constructor() {
super()
this.state = {
topText: "",
bottomText: "",
randomImg: "http://i.imgflip.com/1bij.jpg",
allMemeImgs: []
}
}
componentDidMount() {
fetch("https://api.imgflip.com/get_memes").then(response => response.json())
.then(response => {
const {memes} =response.data
console.log(memes[2])
this.setState({allMemeImgs: memes})
})
}
handleChange = (event) => {
const {name, value} = event.target
this.setState({[name]: value})
}
handleSubmit = (event) => {
event.preventDefault()
const randNum = Math.floor(Math.random() *
this.state.allMemeImgs.length)
const randMemeImg = this.state.allMemeImgs[randNum].url
this.setState({ randomImg: randMemeImg})
}
render() {
return (
<Form
handleChange = {this.handleChange}
data={this.state}
onSubmit={this.handleSubmit}
/>
)
}
}
export default MemeGenerator
The image is supposed to update to a random image every time the button is clicked. But it doesn't, also the whole page reloads, ignoring the event prevent Default
import React from 'react'
import style from './styles.module.css'
function Form(props) {
return (
<div>
<form className={style.memeForm} onSubmit={props.handleSubmit}>
<input
type="text"
placeholder="Type your top text"
name="topText"
value={props.data.topText}
onChange={props.handleChange}
/>
<input
type="text"
placeholder="Type your bottom text"
name="bottomText"
value={props.data.bottomText}
onChange={props.handleChange}
/>
<button>Generate</button>
</form>
<div className={style.meme}>
<img src={props.data.randomImg} alt="" />
<h2 className={style.top}>{props.data.topText}</h2>
<h2 className={style.bottom}>{props.data.bottomText}</h2>
</div>
</div>
)
}
export default Form
change these lines of code
onSubmit={(event) => props.handleSubmit(event)}
and
<button type='submit'>Generate</button>
<form className={style.memeForm} onSubmit={(event) => props.handleSubmit(event)}>
<input
type='text'
placeholder='Type your top text'
name='topText'
value={props.data.topText}
onChange={props.handleChange}
/>
<input
type='text'
placeholder='Type your bottom text'
name='bottomText'
value={props.data.bottomText}
onChange={props.handleChange}
/>
<button type='submit'>Generate</button>
</form>;