Form looses focus after single character input? - reactjs

I created a form with a state attached to it , but after every character input the form looses focus.
i realize its because the state cause the form to re render how do i escape this?
import axios from 'axios'
const App = () => {
const [countries,setCountries] =useState([])
const [ newName,setnewName ] = useState('')
useEffect(()=>{
axios.get('https://restcountries.eu/rest/v2/all')
.then(response=>{
setCountries(response.data)
})
},[])
const handleChange = (event) =>{
setnewName(event.target.value)
}
const Finder = ()=>{
return(
<div>
<form>
<div>
Find country : <input value={newName} onChange={handleChange} />
</div>
</form>
</div>
)
}
return(
<div>
<p>Meow</p>
<Finder/>
</div>
)
}
export default App```

As you are rendering Finder as a component and it will be create a new function on each and every render instead as you are rendering it inside a component invoke it as a function like below
try changing the return statement as
return(
<div>
<p>Meow</p>
{Finder()}
</div>
)
Please go through this sandbox for reference

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.

TSX Input Value

I am developing a web app using React.JS.
I would like the input to be a default value, but the input can't be uneditable.
I have tried :
let [inputValue, setInputValue] = useState<string>('Value of Input')
return (
<div className = "App">
<input value={inputValue}></input>
</div>
The problem with this is that i can't edit the input.
I think you need onChange on that input, and you can change state with that onChange event
const handleOnChange = (event) => {
setInputValue(event.target.value);
};
and you can add h1 to see what's inside the state
<h1>this is what inputValue state content: {inputValue}</h1>
and the whole code will look like this
import { useState } from "react";
export default function App() {
const [inputValue, setInputValue] = useState("Value of Input");
const handleOnChange = (event) => {
setInputValue(event.target.value);
};
return (
<div className="App">
<h1>this is the content of inputValue state: {inputValue}</h1>
<input onChange={(event) => handleOnChange(event)}></input>
</div>
);
}
<input value={inputValue} onChange={(e) => setInputValue(e.target.value)}></input>

type error = assignment to constant variable react.js

import React, { useState } from 'react'
export default function App() {
const [todos , set_todos] = useState([''])
const [input , set_input] = useState('')
const new_todo = (event) =>{
set_todos = ([...todos,input]);
}
return (
<>
<h1>hello world</h1>
let input = <input value={input} onChange={event=> set_input(event.target.value)}/>
<button onClick ={new_todo}>add todo</button>
<ul>
{todos.map(todo =>(
<li>{todo}</li>
))}
</ul>
</>
)
}
the error is in 7th line of the code
i am a totally new beginner so it would be helpful if you explain it to me
If you want to update your state (that is an array) in react hooks, you should try like this :
const new_todo = (input) => set_todos(oldState => [...oldState,input])
with this code, you will not see any error but I have some offer for your code that make it better:
put your inputs such as input and buttons in the form tag
use variable declarations outside of return ( let return be for HTML tag and its better to use your logics outside of return ) make it easier to read
and I think your code can be like this:
import React, { useState } from 'react'
export default function App() {
const [todos , set_todos] = useState([''])
const submitTask = (e) =>{
// Calling preventDefault() during any stage of event flow cancels the event,
// meaning that any default action normally taken by the implementation
// as a result of the event will not occur
e.preventDefault();
const { taskInput } = e.target; // get your input by name
// assign input value to your state
set_todos(oldState => [...oldState, taskInput.value ])
}
return (
<>
<h1>hello world</h1>
<form onSubmit={submitTask}>
<input name="taskInput" />
<button type="submit">add todo</button>
</form>
<ul>
{todos.map(todo =>(
<li>{todo}</li>
))}
</ul>
</>
)
}
You should use set_todos like below:
set_todos([...todos, input]);
Because set_todos is a function. You can find the State Hook's usage in Introducing Hooks.

React.js setState not getting update wiith onclick

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.

Resources