React not displaying text upon form submission - javascript

I'm trying to take input and then display it once the form is submitted but it is not being displayed.
I first use a hook to get the text inside the input field. Once the button is pressed I run a function that uses another hook and sets its value to the text in the input field. This is then put inside the render.
The problem I'm having is that as soon as I submit the form, the screen goes blank.
I have attached my code below.
import React from "react";
import { useState } from "react";
const App = () => {
const [Text, setText] = useState('');
const [Input, setInput] = useState('');
const showInp = (e) => {
e.preventDefault();
setInput(Text);
};
return(
<div className="Main">
<p>
The following cryptocurrencies are available: Bitcoin(BTC).
</p>
<form onSubmit={showInp}>
<label htmlFor="CurrencyName">Currency Name: </label>
<input type="text" className="CurrencyName" value={Text} onChange={(e) => setText(e.target.value)} />
<button style={{marginLeft:"5px"}} type="submit">Submit</button>
</form>
{Input !== '' &&(
{Input}
)}
</div>
)
}
export default App;
Any help would be appreciated.

You have syntax error while rendering Input value. instead of Input value you are rending an object which has Input key and its values is Input, and react can not render objects, it will throw an error.
import React from 'react';
import { useState } from 'react';
const App = () => {
const [Text, setText] = useState('');
const [Input, setInput] = useState('');
const showInp = e => {
e.preventDefault();
setInput(Text);
};
return (
<div className="Main">
<p>The following cryptocurrencies are available: Bitcoin(BTC).</p>
<form onSubmit={showInp}>
<label htmlFor="CurrencyName">Currency Name: </label>
<input
type="text"
className="CurrencyName"
value={Text}
onChange={e => setText(e.target.value)}
/>
<button style={{ marginLeft: '5px' }} type="submit">
Submit
</button>
</form>
{/* Below line had error */}
{Input !== '' && Input}
</div>
);
};
export default App;

Related

React: How to Render Data from Multiple Inputs to Table?

How to Render user (multiple) inputs data to table in React. For single table, its easy to use map function and pass it as prop. But, how to approach for multiple inputs?
More specifically, the code below is working for single user input (here, payerName), i need to render all three user inputs to table! (here, inputs namely: PayerName, itemName, AmountSpent)
Thanks!
Code Reference:
File Name: App.js
import { useState } from "react";
import "./styles.css";
import Row from "./Row";
export default function App() {
const [payerName, setPayerName] = useState("");
const [payerNameArray, setPayerNameArray] = useState([]);
const [itemName, setItemName] = useState("");
const [itemNameArray, setItemNameArray] = useState([]);
const [amountSpent, setAmountSpent] = useState("");
const [amountSpentArray, setAmountSpentArray] = useState([]);
const addRows = (e) => {
e.preventDefault();
setPayerNameArray([...payerNameArray, payerName]);
setItemNameArray([...itemNameArray, itemName]);
setAmountSpentArray([...amountSpentArray, amountSpent]);
};
return (
<div className="App">
<input value={payerName} onChange={(e) => setPayerName(e.target.value)} />
<input value={itemName} onChange={(e) => setItemName(e.target.value)} />
<input value={amountSpent} onChange={(e) => setAmountSpent(e.target.value)} />
<button onClick={addRows}>Submit</button>
{payerNameArray.map((payee, index) => (
<Row payer_name={payee} ukey={index} />
))}
</div>
);
}
File Name: Row.js
const Row = (props) => {
return (
<div key={props.ukey}>
<tr>
<td>{props.payer_name}</td>
</tr>
</div>
);
};
export default Row;
Thanks!

I want to give user error when update form is loaded and user does not change fields and clicks update

import React,{useState,useEffect} from 'react';
import { Button, Form } from 'semantic-ui-react';
import axios from 'axios';
import {useNavigate} from 'react-router';
import usePrevious from './prev';
import {Link} from 'react-router-dom';
const Update = () => {
const [firstName, setFirstName] = useState('');
const [lastName, setLastName] = useState('');
const [checkbox, setCheckBox] = useState(false);
const [id, setID] = useState(null);
let navigate = useNavigate();
Here I am storing the input field's previous value using another component
to get the previous value
const previous = usePrevious(firstName);
useEffect(() => {
setID(localStorage.getItem('ID'));
setFirstName(localStorage.getItem('First Name'));
setLastName(localStorage.getItem('Last Name'));
setCheckBox(localStorage.getItem('Checkbox Value'))
}, []);
This is where the updated data is being sent to mock api and in if condition i am
comparing previous value with new one(if it changes).
const updateApiData = () => {
axios.put(`https://61cb2af8194ffe0017788c01.mockapi.io/fakeData/${id}`,{
firstName,
lastName,
checkbox
}).then(()=>{
navigate('/read');
})
if(firstName==previous){
console.log("change");
}
}
return(
<div>
<Form>
<Form.Field>
<label>First Name</label>
<input id="i1" placeholder='First Name' value={firstName}
onChange={(e)=>setFirstName(e.target.value)}
/>
</Form.Field>
<Form.Field>
<label>Last Name</label>
<input placeholder='Last Name' value={lastName}
onChange={(e)=>setLastName(e.target.value)} />
</Form.Field>
here on button click i am calling the function of sending data to api.
i need to check here if on click update the field's value is same as the previous one.
<Button type='submit' onClick={updateApiData}>Update</Button>
<Link to="/read">
<Button>Cancel</Button>
</Link>
</Form>
<br></br>
<Button onClick={()=>navigate(-1)}>Go Back</Button>
</div>
)
}
export default Update;

how to update dropdown list by clicking the update button in react

I want to give some text in input field and after clicking the update button it should be update in the dropdown list but its not working
import React from "react";
export default function DropDown() {
const [input, setInput] = React.useState('');
const selectproject=({e})=>{
setInput(e.target.value);
}
return (
<>
<select>
<option>{input?input:'null'}</option>
</select>
<br/><br/>
<input value={input} /><button onClick={selectproject}>Update</button>
</>
);
}
remove curly braces on selectproject props.
selectproject=(e)=>{
setInput(e.target.value);
}
you are destructuring e in <Event> which is not available. if you want to destructuring it, try this instead
selectproject=({target: {value}})=>{
setInput(value);
}
if you want dropdown list to be updated after clicking button, you'll need another state
import React from "react";
export default function DropDown() {
const [input, setInput] = React.useState("");
const [project, setProject] = React.useState("");
const selectproject = () => {
setProject(input);
};
const handleOnChange = (e) => {
setInput(e.value.target);
};
return (
<>
<select>
<option>{project ? project : "null"}</option>
</select>
<br />
<br />
<input value={input} onChange={handleOnChange} />
<button onClick={selectproject}>Update</button>
</>
);
}
Need to remove curly brace around e and set onchange to input:
import React from "react";
export default function DropDown() {
const [input, setInput] = React.useState("");
const selectproject = (e) => {
setInput(e.target.value);
};
return (
<>
<select>
<option>{input ? input : "null"}</option>
</select>
<br />
<br />
<input value={input} onChange={selectproject} />
<button onClick= {selectproject}>Update</button>
</>
);
}
You can use from two useState:
import React from "react";
function DropDown() {
const [input, setInput] = React.useState('');
const [select,setSelect] = React.useState('');
const selectproject = () => {
setSelect(input);
}
const handleChange = (e) => {
setInput(e.target.value);
}
return (
<>
<select>
<option>{select?select:'null'}</option>
</select>
<br/><br/>
<input onChange={handleChange} value={input} /><button onClick={selectproject}>Update</button>
</>
);
}

Different value in browser and in console

Can someone please explain to me why in this code when I type a character the character that appears in the label tag is different from the character that appears on the console? Is the code correct?
import React, { useState } from "react";
const App = () => {
const [text, settext] = useState("");
const update = (e) => {
settext(e.target.value);
console.log(text);
};
return (
<div>
<input type="text" value={text} onChange={update} />
<label>{text}</label>
</div>
);
};
export default App;
The settext doesn't update the text state instantly. So calling console.log(text) right after it will give interesting results.
What you want to use is useEffect to log out the value of text.
import React, { useState, useEffect } from "react";
const App = () => {
const [text, settext] = useState("");
const update = (e) => {
settext(e.target.value);
};
useEffect(() => console.log(text), [text]);
return (
<div>
<input type="text" value={text} onChange={update} />{" "}
<label> {text} </label>{" "}
</div>
);
};
export default App;

how to get input field value on button click in react?

Could you please tell me how to get input field value on button click in react , I am using react hooks .I want to get first name and lastname value on button click. I already pass name attribute in my function component.
Here is my code
import React, { Component, useState } from 'react';
import { render } from 'react-dom';
export default function InputField({name,label}) {
const [state, setState] = useState('')
return (
<div>
<label>{label}</label>
<input type="text"
value={state}
name={name}
onChange={(e) => setState(e.target.value)} />
{state}
</div>
);
}
Use <form> tag with useRef hook
Wrap your <InputField> tags with an html <form> tag and put a react ref on the later. Like this:
import React, { Component, useRef } from 'react'
import { render } from 'react-dom'
import InputField from './inputfield'
import './style.css'
function App () {
const nameForm = useRef(null)
const handleClickEvent = () => {
const form = nameForm.current
alert(`${form['firstname'].value} ${form['lastname'].value}`)
}
return (
<div>
<form ref={nameForm}>
<InputField label={'first name'} name={'firstname'}/>
<InputField label={'last name'} name={'lastname'}/>
</form>
<button onClick={handleClickEvent}>gett value</button>
</div>
)
}
render(<App />, document.getElementById('root'))
Working example: https://stackblitz.com/edit/react-shtnxj
The Easiest Way For Me is useRef
With useRef it's pretty simple. Just add ref name and then submit.
const email = useRef(null);
function submitForm(e){
e.preventDefault();
console.log(email.current.value);
}
return (
<div>
<form onSubmit={submitForm}>
<input type="text" ref={email} />
<button>Submit</button>
</form>
</div>
)
You could always lift up the state in parent component.
codeSandbox link
Parent Component
import React from "react";
import ReactDOM from "react-dom";
import ChildComponent from "./Child";
const { useState } = React;
function App() {
const [first_name, setFirstName] = useState("");
const [last_name, setLastName] = useState("");
const handleFirstNameChange = ({ target }) => {
setFirstName(target.value);
};
const handleLastNameChange = ({ target }) => {
setLastName(target.value);
};
const handleClick = () => {
console.log(first_name);
console.log(last_name);
};
return (
<div className="App">
<ChildComponent
label="first name"
onChange={handleFirstNameChange}
value={first_name}
/>
<ChildComponent
label="last name"
onChange={handleLastNameChange}
value={last_name}
/>
<button onClick={handleClick}>Click me</button>
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Child Component
import React from "react";
const ChildComponent = ({ label, onChange, value, name }) => {
return (
<div>
<label>{label}</label>
<input type="text" value={value} name={name} onChange={onChange} />
</div>
);
};
export default ChildComponent;
You could always combine onChange handler for first name and last name.
Hope that helps!!!
A good solution is to move the state from InputField component into index:
const [F_name, setF_name] = useState('')
const [L_name, setL_name] = useState('')
now you should pass state value and event handler to InputField to change the state when input is changed:
<InputField label={'first name'} name={'firstname'} value={F_name} changed={(name) => setF_name(name)}/>
In Your InputField field: edit it to be like:
<input type="text"
value={value}
name={name}
onChange={(e) => changed(e.target.value)} />
See Working Demo Here
import React, { useRef } from 'react'
const ViewDetail = () => {
const textFirstName = useRef(null)
const onChange = e => {
console.log(textFirstName.current.state.value)
}
return <Input maxLength={30} ref={textFirstName} placeholder="Nombre" onChange=onChange} />
}
I can think of these approaches -
You can pull the state up to the parent component.
App.js
const [user, setUser] = useState('');
return (
<Inputfield setValue={setUser} value={user} />
);
InputField.js
<input value={props.value} onChange={(e) => setValue(e.target.value)} />
You can use ref to access indiviual element value.
If you have data distributed across multiple components you can also make use of Context API
Hope this helps!
Do let me know if you need more info on any of the option. Thanks!
You should do the react hooks work on your index and pass the value and the onChange function to your InputField component.
//index page
import React, { Component, useState } from 'react';
import { render } from 'react-dom';
import InputField from './inputfield';
import './style.css';
function App() {
const [firstname, setFirstName] = useState('');
const [lastname, setLastName] = useState('');
const handleClickEvent = ()=>{
setFirstName('Will');
setLastName('smith');
}
return (
<div>
<InputField
label={'first name'}
name={'firstname'}
value={firstname}
onChange={setFirstName}
/>
<InputField
label={'last name'}
name={'lastname'}
value={lastname}
onChange={setLastName}
/>
<button
onClick={handleClickEvent}
>Get value</button>
</div>
);
}
render(<App />, document.getElementById('root'));
// input field
import React, { Component, useState } from 'react';
import { render } from 'react-dom';
export default function InputField({name,label, value, onChange}) {
return (
<div>
<label>{label}</label>
<input type="text"
value={value}
name={name}
onChange={(e) => onChange(e.target.value)} />
{value}
</div>
);
}
While keeping the majority of your structure the same, I think the simplest and most React solution is to use forwardRef() which in a nut-shell let's us communicate between then parent-component and child-components.
See working sandbox.
App.js
import React, { useRef } from "react";
import InputField from "./InputField";
import ReactDOM from "react-dom";
function App() {
const handleClickEvent = () => {
if (firstName.current && lastName.current) {
console.log(`firstName: ${firstName.current.value}`);
console.log(`lastName: ${lastName.current.value}`);
}
};
const firstName = useRef(null);
const lastName = useRef(null);
return (
<div>
<InputField ref={firstName} label={"first name"} name={"firstname"} />
<InputField ref={lastName} label={"last name"} name={"lastname"} />
<button onClick={handleClickEvent}>Get value</button>
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
InputField.js
import React, { useState } from "react";
const InputField = React.forwardRef((props, ref) => {
const [state, setState] = useState("");
return (
<div>
<label>{props.label}</label>
<input
ref={ref}
type="text"
value={state}
name={props.name}
onChange={e => setState(e.target.value)}
/>
{state}
</div>
);
});
export default InputField;
Notice that with this structure, you are not required to pass in any state updating function as props to the InputField component. The value that you enter into each input will be strictly maintained by the individual component. It is independent from the Parent, and therefore makes it much more reusable.
The refs we created allow us to tap into specific elements of the InputField so we extract the desired values. In this case, we can get first-name and last-name through the handleClickEvent function.
you can achieve this doing the following:
import React, { Component, useState } from 'react';
import { render } from 'react-dom';
export default function InputField({name,label}) {
const [state, setState] = useState('');
const handleChange = e => {
setState(e.target.value);
};
return (
<div>
<label>{label}</label>
<input
type="text"
value={state}
name={name}
onChange={handleChange}
/>
{state}
</div>
);
}
Hopes this helps.
well one simple(but not necessarily recommended) way is to provide an id or a ref like this in index.js
<InputField label={'first name'} name={'firstname'} id={"ip1"}/>
<InputField label={'last name'} name={'lastname'} id={"ip2"}/>
and in your inputfield.js pass the id props to the input fields like this
<input type="text"
value={state}
name={name}
onChange={(e) => setState(e.target.value)}
id= {id}/>
Now you can call them in the onClick of the button like this in index.js
const handleClickEvent = ()=>{
alert(document.getElementById("ip1").value);
}
The second, more preferable way is to set the state variable in index.js
function App() {
const [stateIp1, setStateIp1] = useState('');
const [stateIp2, setStateIp2] = useState('');
const handleClickEvent = ()=>{
alert(stateIp1);
}
return (
<div>
<InputField label={'first name'} state={stateIp1} setState={setStateIp1} name={'firstname'} id={"ip1"}/>
<InputField label={'last name'}state={stateIp2} setState={setStateIp2} name={'lastname'} id={"ip2"}/>
<button
onClick={handleClickEvent}
>Get value</button>
</div>
);
}
Now your inputfield.js becomes
export default function InputField({name,label,id,setState,state}) {
return (
<div>
<label>{label}</label>
<input type="text"
value={state}
name={name}
onChange={(e) => setState(e.target.value)} id= {id}/>
</div>
);

Categories