React.js setState not getting update wiith onclick - reactjs

This is my sample code, it's very basic i just want to console fname once submit is clicked.
When i pressed first time i get an empty line but when pressed second time the button i get some empty value. I am attaching the screenshot for the console.
I dont want to change my code to a class and use some method to get the value in console.
screenshot for console output
import React,{useState} from 'react'
export const anyComponent = () => {
const [fname, setFname] = useState('')
const submit = (event) =>{
setFname({fname: [event.target.value] })
console.log(fname)
}
return(
<div>
<input name="fname" type="text" placeholder="Enter your First Name" />
<button onClick={submit}>Submit</button>
</div>
)
}

From MDN Docs:
The target property of the Event interface is a reference to the object onto which the event was dispatched.
In your case, event.target would point to the button and not input.
What you need is a reference to the input, you can use useRef hook for it like this
import React, { useState, useRef } from "react";
export default anyComponent = () => {
const inputEl = useRef(null);
const [fname, setFname] = useState("");
const submit = event => {
setFname({ fname: [inputEl.current.value] });
};
console.log(fname);
return (
<div>
<input
name="fname"
ref={inputEl}
type="text"
placeholder="Enter your First Name"
/>
<button onClick={submit}>Submit</button>
</div>
);
};
Also, setState is asynchronous, that's why you wouldn't see the result in the console just after calling setFname. However you'd see the updated fName in console on the next render, that's why I've moved it out of the submit.
Without useRef
Alternatively, you can add onChange handler on input and update the state fname from there
function App(){
const [fname, setFname] = useState("");
const submit = () => {
console.log(fname);
};
const handleChange = ev => {
setFname({ fname: [ev.target.value] });
}
return (
<div>
<input
name="fname"
onChange={handleChange}
type="text"
placeholder="Enter your First Name"
/>
<button onClick={submit}>Submit</button>
</div>
);
};

Your console log should be outside submit method. Or log event.target.value instead fname.

Related

React onClick button is not triggering the function

I am developing an chrome extension where i need to authentication user but a very simple onClick button which calls a function is not working
this is the simple code where i want to show info on console when button is clicked
import React, { useState } from 'react';
const Login = () => {
const [user, setuser] = useState("");
const handleSubmit = (data) => {
data.preventDefault();
console.log("usernae: ");
console.log("Data: ", data.target);
}
const getInputValue = (event) => {
console.log(event.target.value)
// Select input element and get its value
console.log("I am heresdfg")
// let inputVal = document.getElementsByClassName("usernameInputField")[0].value;
// Display the value
// alert(inputVal);
}
return (
<div
id="login-form">
<p>
<div className='form'>
</div>
<input type="text"
id="username"
name="username"
className='usernameInputField'
value={user}
onChange={(event => setuser(event.target.value))}
placeholder="Username" required />
</p>
<p>
<button onClick={getInputValue} type="button" id="login">button</button>
</p>
</div>
);
};
export default Login;
It seems like you want the input value value inside the event handler if I'm not wrong, you can get it from the state - user as
const getInputValue = (event) => {
console.log(user)
}
as the event would be button's you wouldn't get the value of input from it's event and it is not required too as it's already in the react's state ....
Example:
const {useState} = React;
const App = () => {
const [name, setName] = useState("");
const submitHandler = () => {
console.log(name)
}
return (
<div>
Name: <input type="text" value={name} onChange={(e)=>setName(e.target.value)}/>
<button onClick={submitHandler}>Submit</button>
</div>
);
};
ReactDOM.createRoot(
document.getElementById("root")
).render(
<App/>
);
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.1.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.1.0/umd/react-dom.development.js"></script>
In the getInputValue function event is pointing to the button.
Change the event.target.value to user if you want to print the text into the console.
Here's the codesandbox.
If you don't want to use the value from useState then you can also check useRef hook which works in a similar way.

how to get data from input form in React js by clicking submit button and create a div element that get all data user input. {.map() Multiple states}

I'd like to create div with data getting from user input by clicking btn submit, But I don't know how. I am new in react js.
This is my App.js file:
import './App.css';
import './RegisterApp.css'
import RegisterApp from './Components/RegisterApp';
function App() {
return (
<div className="App">
<RegisterApp />
</div>
);
}
export default App;
and this is my component file RegisterApp.js:
import React, {useState} from 'react'
function RegisterApp() {
const [name, setName] = useState('Khun Neary')
const [position, setPosition] = useState('Designer')
const [list, setList] = useState({name, position})
const formSubmit = (e) => {
e.preventDefault()
setList(...list, name)
setList(...list, position)
console.log(list);
}
return (
<div className='container'>
<form className='form-box' onSubmit={formSubmit}>
<button>Upload Profile</button>
<input
type="text"
placeholder='Name...'
value={name}
onChange={(e) => setName(e.target.value)}
/>
<input
type="text"
placeholder='Position...'
value={position}
onChange={(e) => setPosition(e.target.value)}
/>
<button>Submit</button>
</form>
<div className='register-box'>
<div className='sub-reg-box'>
<div className='img-box'></div>
<div className='detail-box'>
<h2>{name}</h2>
<h4>{position}</h4>
</div>
</div>
</div>
</div>
)
}
export default RegisterApp
enter image description here
I'd like to create div element after I click submit btn and display all the data get from input by user.
add type="submit" to button
<button type="submit">Submit</button>
then update the list state
const formSubmit = (e) => {
setList( {...list, name, position })
}
you won't see the update to the list immediately since setState in asynchronous. But to check that, you can use useEffect
useEffect(() => {
console.log(list)
},[list])
You don't need to "get" the data. You already have it in the variables name and position. You should create an onClick handler for the button that uses these values.
Note that setList() is misnamed. You should use an object here. In fact, you can get rid of list and setList because you already have name, setName, position and setPosition. You don't need both.

Input component > feeds Forms component - how to handle submit?

I am missing how to bring the input value out of the child component.
I have an Input component that I want to re-use, there I can see what happens onChange, and I see every change on the input field.
Then on the parent component, Form, where I use <Input />, I have the rest of the form with the Submit button. At this level, I want to handle onSubmit, but I cannot see/console the value of the input here. I can only see it from the child.
Any ideas about what I am doing wrong?
Input.js - here I can see the input value onChange
function Input(props) {
const { label, name, value } = props;
const handleChange = (event) => {
const updateForm = {...Form};
console.log("change:", updateForm)
updateForm[label] = event.target.value;
}
return (
<label>
{label}
<input name={name} value={value} onChange={handleChange}></input>
</label>
)
}
export { Input }
Forms.js - here I cannot get access to the input value and submit/handle it
function Form(props) {
const handleSubmit = (event) => {
event.preventDefault();
console.log(Input.value);
console.log(props.label.value)
alert(`form is: ${event.target.input}`);
}
return (
<>
<form onSubmit={handleSubmit}>
<Input label={props.label} />
<input type="submit" value="Submit"></input>
</form>
</>
)
}
I have that structure because I am defining what I want in my Form on the main HomePage component:
function Home() {
return (
<>
.......
<Section withForm label={["Name"]} {...homeObjFive}/>
<Section withForm label={"Phone"} {...homeObjOne}/>
.......
</>
)
}
This is the perfect case to use the useRef function from react.
In Form.js
import React, { useRef } from 'react'
create a reference constant and pass it as a prop into the input component. and change the input value that is handled in the onSubmit function to the reference
Also in Form.js (changes are made to the submit function)
function Form(props) {
const { inputValue } = useRef(); // added
const handleSubmit = (event) => {
event.preventDefault();
console.log(inputValue); // changed
console.log(props.label.value)
alert(`form is: ${event.target.input}`);
}
return (
<>
<form onSubmit={handleSubmit}>
{/* added the inputValue prop to the input component */}
<Input label={props.label} inputValue={inputValue} />
<input type="submit" value="Submit"></input>
</form>
</>
)
}
and now inside of the Input component set the input elements reference to the inputValue prop. you will no longer need a onChange function as reacts useRef function is updated automatically
In Input.js
function Input(props) {
return (
<label>
{props.label}
<input name={props.name} value={props.value} ref={props.inputValue}></input>
</label>
)
}
export { Input }
Suppose you have a form with two inputs, name and email (these are the id props of the inputs). You can extract the form values like this:
const handleSubmit = (event) =>
{
event.preventDefault()
const data = new FormData(event.currentTarget)
const name = data.get('name')
const email = data.get('email')
// do something with the data
}
You can read more about FormData here.

cannot clear form field with functional react hook in reactjs

The code below works fine by submit a post message. now i want to clear the message input form on form submission but cannot get it to work. I have tried the following 3 options but yet no luck.
1.)
function clearState() {
message('');
}
// pass the clear state function on form submission
clearState();
2.) Clear form by referencing the form id
document.getElementById('my_form').reset();
3.) using event target reset
event.target.reset();
here is the full code.
import React, { useState, useRef, useEffect } from "react";
export default function App(props) {
const [message, setMessage] = useState("");
const [messages, setMessages] = useState([]);
const currentDate = new Date();
useEffect(() => {
// fetch content axio or ajax
}, []);
function clearState() {
message('');
}
function handleChange(event) {
setMessage(event.target.value);
}
function handleSubmit(event) {;
event.preventDefault();
const newMessages = messages;
const data = { message: message, date: new Date() };
setMessages(newMessages.concat([data]));
//clear all form field based on form id
clearState();
//document.getElementById('my_form').reset();
//event.target.reset();
}
return (
<React.Fragment>
<div className="chat_container">
{messages.map((m, e) => (
<div key={e}>
<div className="chat_message">
chat: {m.message} ---{m.date.toLocaleTimeString()}
</div>
</div>
))}
</div>
<div className="myFooter">
<form id"my_form" onSubmit={handleSubmit}>
<label>
Name:
<input type="text" value={message} onChange={handleChange} />
</label>
<input type="submit" value="Submit" />
</form>
</div>
</React.Fragment>
);
}

trying to clear all form fields using a hook function in React. Adding object to onClick event

I have created the following hook in a small React project project.
import { useState } from "react";
export default initialValue => {
const [name, setValue] = useState(initialValue);
const handleChange = e => {
setValue(e.target.value);
};
const reset = () => {
setValue("");
};
return [name, reset, handleChange];
};
Now in my App.js I have imported the hook. I have the following code that uses the hook to populate the form.
import React from "react";
import useInputHook from "../Hooks/useFormState";
function App() {
const [name, setName, resetName] = useInputHook("");
const [surname, setSurname, resetSurname] = useInputHook("");
const [email, setEmail, resetEmail] = useInputHook("");
This issue I am having is using the resetName, resetSurname and resetEmail on the onClick event.
to clear the form fields. I get the following error /src/components/App.jsx: Unexpected token, expected "..." (41:35)
Below is the code for the form.
return (
<div className="container">
<h1>
Hello {name} {email}
</h1>
<h2>{email}</h2>
<input
onChange={setName}
type="text"
placeholder="What's your name?"
value={name}
/>
<input
onChange={setSurname}
type="text"
placeholder="What's your surname?"
value={surname}
/>
<input
onChange={setEmail}
type="text"
placeholder="What's your email?"
value={email}
/>
<button onClick={resetName} {resetSurname} {resetEmail}>Submit</button>
</div>
);
}
Any help would be appreciated.
you have exported as [value, reset function, change handler]
and imported as [value, change handler, reset function] (wrong order)
the reset button at the bottom should activate all reset function as well like this:
<button onClick={()=>resetName();resetSurname();resetEmail();}>Submit</button>
if you are setting your functions like that in the button they would become a props for the button and not get executed when onClick is firing.
this is wrong: <button onClick={resetName} {resetSurname} {resetEmail}>Submit</button>
you can try make a reset array of functions or play with useEffect cleanup function.
happy reacting!

Resources