I am unable to pass props from parent to child in React - javascript

Starting out with react, I have created an input field in the parent component, When the user submits the text, I am passing down the text to the child component and printing the text under the parent component.
Code of parent component
import React, { useState } from "react";
import Validate from "./Validate";
function CommandEntry() {
const [value, setValue] = useState("");
const handleSubmit = e => {
e.preventDefault();
// console.log(value);
return <Validate value={value} />;
};
return (
<div>
<form onSubmit={handleSubmit}>
enter text:~
<input
type="text"
autoFocus
required
onChange={e => setValue(e.target.value)}
/>
</form>
</div>
);
}
export default CommandEntry;
Code of child component
import React from "react";
export default function Validate(props) {
console.log("I am in child");
return (
<div>
<h1>{props.value}</h1>
</div>
);
}

You would need to render the child inside return and the set the value in handler.
Like so:
function CommandEntry() {
const [value, setValue] = useState("");
const [submit, setSubmitValue] = useState(false);
const handleChange = e => {
e.preventDefault();
setValue(e.target.value); //setting the value on change
};
const handleSubmit = e => {
e.preventDefault();
setSubmitValue(true); //setting the submit flag to true.
};
return (
<div>
value &&
<form onSubmit={handleSubmit}> // submit handler
enter text:~
<input
type="text"
autoFocus
required
onChange={handleChange} // change handler
/>
{submit &&
<Validate value={value} /> // rendering the child component
}
</form>
</div>
);
}

You can't return a JSX element from a handler function. Handler functions are different and render functions are different. So here you can change this in your parent component in which child will be shown only when submit is true.
import React, { useState } from "react";
import Validate from "./Validate";
function CommandEntry() {
const [value, setValue] = useState("");
const [submit, setSubmitValue] = useState(false);
const handleSubmit = e => {
e.preventDefault();
setSubmitValue(true);
};
return (
<div>
<form onSubmit={handleSubmit}>
enter text:~
<input
type="text"
autoFocus
required
onChange={e => setValue(e.target.value)}
/>
</form>
{submit && <Validate value={value} />}
</div>
);
}
export default CommandEntry;

Related

Next.js trying to push data from input value into json, but onSubmit doesn't work at all

I'm trying to put input value into json file, but submit button doesn't work, can you help me with it?
import PcosData from "/data/pcos.json";
import {useEffect} from "react";
import { useState } from "react";
export default function adminPcos() {
// const CreateMePanel = () => {
const [title, setTitle] = useState(PcosData["pcos-first"].title);
const [time, setTime] = useState(PcosData["pcos-first"].time);
const handleSubmit = (e) => {
PcosData["pcos-first"].title = title;
PcosData["pcos-first"].time = time;
}
return (
<div>
<h1>hello world</h1>
{PcosData["pcos-first"].map((pcosdata) => (
<form onSubmit={handleSubmit} key={ pcosdata.id } method="post">
<input type="text" name={title} defaultValue={pcosdata.title} onChange={(e) => setTitle({text: e.target.value})}/>
<input type="text" name={time} defaultValue={pcosdata.time} onChange={(e) => setTime({text: e.target.value})}/>
<input type="submit" value="submit"/>
</form>
))}
</div>
)
}
i checked all of the functions, variables, but didn't find any errors

How to pass multiple onChange form data from child to parent element in react

I am trying to print real-time user input from input tags by the user. I am even getting multiple user inputs from the child element to the parent element as a form of an object using useState. But whenever the user tries to fill the second input field, then the first input is re-render and it's replaced by the primary state which is an empty string.
code:-
Child Element
import React, { useState } from "react";
const Child = (props) => {
const [name, setName] = useState("");
const [age, setAge] = useState("");
let userData = {
name: "",
age: ""
};
const nameChangeHandler = (e) => {
setName(e.target.value);
userData.name = e.target.value;
};
const ageChangeHandler = (e) => {
setAge(e.target.value);
userData.age = e.target.value;
};
const formOnChageHandler = (e) => {
e.preventDefault();
props.getData(userData);
};
const fromOnSubmitHandler = (e) => {
e.preventDefault();
};
return (
<React.Fragment>
<form onChange={formOnChageHandler} onSubmit={fromOnSubmitHandler}>
<label htmlFor="name">Name:</label>
<input
id="name"
placeholder="Enter Name"
value={name}
onChange={nameChangeHandler}
/>
<br />
<label htmlFor="age">Age:</label>
<input
id="age"
placeholder="Enter Age"
value={age}
onChange={ageChangeHandler}
/>
</form>
</React.Fragment>
);
};
export default Child;
Parent Element
import React, { useState } from "react";
import Child from "./components/Child";
function App() {
const [name, setName] = useState("");
const [age, setAge] = useState("");
let userData = (data) => {
setName(data.name);
setAge(data.age);
};
return (
<React.Fragment>
<Child getData={userData} />
<h1>Your name is:{name}</h1>
<h1>Your age is:{age}</h1>
</React.Fragment>
);
}
export default App;
code sandbox Link- https://codesandbox.io/s/from-traversing-child-to-parent-to-another-child-ynwyqd?file=/src/App.js:0-441
How I can get both data being reflected by using onChange from child to parent element?
I suggest you accumulate the user data in one state.
Like this.
const [user, setUser] = useState({
name: "",
age: null
});
And put the state on the parent and pass as props, also just have one handleChange function to update both the name and age by the input id
Child.js
import React, { useState } from "react";
const Child = ({ user, setUser }) => {
const handleChange = (e) => {
setUser((prev) => ({
...prev,
[e.target.id]: e.target.value
}));
};
const formOnChageHandler = (e) => {
e.preventDefault();
};
const fromOnSubmitHandler = (e) => {
e.preventDefault();
};
return (
<React.Fragment>
<form onChange={formOnChageHandler} onSubmit={fromOnSubmitHandler}>
<label htmlFor="name">Name:</label>
<input
id="name"
placeholder="Enter Name"
value={user.name}
onChange={handleChange}
/>
<br />
<label htmlFor="age">Age:</label>
<input
id="age"
placeholder="Enter Age"
value={user.age}
onChange={handleChange}
/>
</form>
</React.Fragment>
);
};
export default Child;
App.js
import React, { useState } from "react";
import Child from "./components/Child";
function App() {
const [user, setUser] = useState({
name: "",
age: null
});
return (
<React.Fragment>
<Child user={user} setUser={setUser} />
<h1>Your name is:{user.name}</h1>
<h1>Your age is:{user.age}</h1>
</React.Fragment>
);
}
export default App;
CODESANDBOX
Try using the child component as below,
import React, { useState } from "react";
const Child = (props) => {
const [name, setName] = useState("");
const [age, setAge] = useState("");
let userData = {
name: name, // the value "name" comes for the local state will be listen to the onChange event every time
age: age // same applies here as well
};
const nameChangeHandler = (e) => {
setName(e.target.value);
};
const ageChangeHandler = (e) => {
setAge(e.target.value);
};
const formOnChageHandler = (e) => {
e.preventDefault();
props.getData(userData);
};
const fromOnSubmitHandler = (e) => {
e.preventDefault();
};
return (
<React.Fragment>
<form onSubmit={fromOnSubmitHandler}>
<label htmlFor="name">Name:</label>
<input
id="name"
placeholder="Enter Name"
value={name}
onChange={nameChangeHandler}
/>
<br />
<label htmlFor="age">Age:</label>
<input
id="age"
placeholder="Enter Age"
value={age}
onChange={ageChangeHandler}
/>
</form>
</React.Fragment>
);
};
export default Child;
just use simple one state to manage data. just take a look below example component created from your child component.
we simply use single object state.
use name prop as key to store value in state.
import React, { useState } from "react";
const Child = (props) => {
const [formData, setFormData] = useState({});
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setFormData({
...formData,
[e.target.name]: e.target.value,
});
};
const formOnChageHandler = (e) => {
e.preventDefault();
props.getData(userData);
};
const fromOnSubmitHandler = (e) => {
e.preventDefault();
};
return (
<React.Fragment>
<form onChange={formOnChageHandler} onSubmit={fromOnSubmitHandler}>
<label htmlFor="name">Name:</label>
<input
id="name"
placeholder="Enter Name"
value={name}
onChange={handleChange}
name="name"
/>
<br />
<label htmlFor="age">Age:</label>
<input
id="age"
placeholder="Enter Age"
value={age}
onChange={handleChange}
name="age"
/>
</form>
</React.Fragment>
);
};
export default Child;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
it happens because you dont watch to the state, try this:
Child.js
import React, { useState } from "react";
const Child = (props) => {
const [name, setName] = useState("");
const [age, setAge] = useState("");
let userData = {
name,
age
};
const nameChangeHandler = (e) => {
setName(e.target.value);
userData.name = e.target.value;
};
const ageChangeHandler = (e) => {
setAge(e.target.value);
userData.age = e.target.value;
};
const formOnChageHandler = (e) => {
e.preventDefault();
props.getData(userData);
};
const fromOnSubmitHandler = (e) => {
e.preventDefault();
};
return (
<React.Fragment>
<form onChange={formOnChageHandler} onSubmit={fromOnSubmitHandler}>
<label htmlFor="name">Name:</label>
<input
id="name"
placeholder="Enter Name"
value={name}
onChange={nameChangeHandler}
/>
<br />
<label htmlFor="age">Age:</label>
<input
id="age"
placeholder="Enter Age"
value={age}
onChange={ageChangeHandler}
/>
</form>
</React.Fragment>
);
};
export default Child;
Try this, i check in codesandbox and it works:
In App.js:
import React, { useState } from "react";
import Child from "./components/Child";
function App() {
const [name, setName] = useState("");
const [age, setAge] = useState("");
return (
<React.Fragment>
<Child name={name} age={age} setName={setName} setAge={setAge} />
<h1>Your name is:{name}</h1>
<h1>Your age is:{age}</h1>
</React.Fragment>
);
}
export default App;
In Child.js:
import React, { useState } from "react";
const Child = ({ name, age, setName, setAge }) => {
const nameChangeHandler = (e) => {
setName(e.target.value);
};
const ageChangeHandler = (e) => {
setAge(e.target.value);
};
const fromOnSubmitHandler = (e) => {
e.preventDefault();
};
return (
<React.Fragment>
<form onSubmit={fromOnSubmitHandler}>
<label htmlFor="name">Name:</label>
<input
id="name"
placeholder="Enter Name"
value={name}
onChange={nameChangeHandler}
/>
<br />
<label htmlFor="age">Age:</label>
<input
id="age"
placeholder="Enter Age"
value={age}
onChange={ageChangeHandler}
/>
</form>
</React.Fragment>
);
};
export default Child;
If you want to improve your code, you can research and use state management like: redux, zustand, react context,...
Hope it useful for you.

Need to Pass props to other components in hook

i want to pass a prop from one(App.jsx) component to other component(form.jsx) in state hooks
App.jsx
import React, {useEffect, useState} from 'react';
import Form from './components/Form';
import Table from './components/Table';
import axios from 'axios';
const App = () => {
const [data, setData] = useState({data:[]});
const [editData, setEditData] = useState([]);
const create = (data) => {
axios.post('http://localhost:5000/info',data).then((res) =>{
getAll();
})
}
useEffect(() =>{
getAll();
},[])
const getAll = () =>{
axios.get("http://localhost:5000/info").then((response) =>{
setData({
data:response.data
})
})
}
const update = event =>{
setEditData(data)
console.log(data); // THIS "data" is the prop that i need to pass to Form.jsx component
}
return (
<div>
<div>
<Form myData={create} editForm={editData} />
</div>
<div>
<Table getData={data} edit={update} />
</div>
</div>
);
};
export default App;
i want that "data" value form App.jsx component as props in this Form.jsx component
Form.jsx
import React, {useState} from 'react';
const Form = (props) => {
const [formData, setFormData] = useState({ Name:'', Age:'', City:''});
const infoChange = e => {
const { name,value} = e.target;
setFormData({
...formData,
[name]: value,
})
}
const infoSubmit = e =>{
e.preventDefault();
let data={
Name:formData.Name,
Age:formData.Age,
City:formData.City
}
props.myData(data);
}
const componentWillReceive = (props) => { // i want the props data here
console.log(props.data); // in class component they use componentWillReceiveRrops ,
} // is there any alternative for function based component to receive props?
return (
<div>
<form onSubmit={infoSubmit} autoComplete="off">
<div>
<label>Name:</label>
<input type="text" onChange={infoChange} name="Name" value={formData.Name} placeholder="Enter Name" />
</div>
<div>
<label>City:</label>
<input type="text" onChange={infoChange} name="City" value={formData.City}
placeholder="Enter City" />
</div>
<div>
<label>Age:</label>
<input type="text" onChange={infoChange} name="Age" value={formData.Age} placeholder="Enter Age" />
</div>
<button type="submit">Submit</button>
</form>
</div>
);
};
export default Form;
i have commented the area of problem within the code , you can ignore the return () block of code.
Sorry for silly questions but THANKYOU Very Much !!! in advance
Use the following code in Form.jsx, the useEffect will listen the change of props.data and update the value
useEffect(() => {
setFormData(props.data);
},
[props.data]);
For more information, you may check the following answer
https://stackoverflow.com/a/65842783/14674139

How to use usestate with object in ReactJS?

I am trying to write a simple program that allows you to enter your first and last name in input fields so you get a greeting based on your name. But I cannot get it to work.
import "./styles.css";
import React, { useState } from "react";
export default function App() {
const [Savedinput, setSavedinput] = useState({Fname:' ' , Lastname:''} );
const ChangeFirst = (e) => {
setSavedinput Savedinput.Fname(e.target.value);
};
const ChangeLast = (e) => {
setSavedinput Savedinput.Lastname(e.target.value);
console.log(e.target.value);
};
return (
<div className="App">
<input type="Text" onChange={ChangeFirst}></input>
<input type="Text" onChange={ChangeLast}></input>
<h1> hello {Fname} {Lastname} </h1>
</div>
);
}
You can use destructure method.
import "./styles.css";
import React, { useState } from "react";
export default function App() {
const [Savedinput, setSavedinput] = useState({Fname:' ' , Lastname:''} );
const onInputChange = (e, attr) =>{
setSavedinput({...Savedinput, [attr]: e.target.value});
}
return (
<div className="App">
<input type="Text" onChange={(e)=>{onInputChange(e, 'Fname)}} value={Savedinput.Fname}></input>
<input type="Text" onChange={(e)=>{onInputChange(e, 'Lastname)}} value={Savedinput.Lastname}></input>
<h1> hello {Savedinput.Fname} {Savedinput.Lastname} </h1>
</div>
);
}
You shouldn't mutate state directly
To change the a state object you can use spread operator. So your code would be something like:
const ChangeFirst = (e) => {
setSavedinput({...SavedInput, Fname: e.target.value})
};
const ChangeLast = (e) => {
setSavedinput({...SavedInput, Lastname: e.target.value})
};
The {...SavedInput} will expand the whole object to the argument and then adding the Fname: ... will overwrite that so the new value will be passed instead.
For more advance usage of form I recommend you to use react-hook-form
You can have 2 states for firstName and lastName
export default function App() {
const [firstName, setFirstName] = useState('');
const [lastName, setLastName] = useState('');
return (
<div className="App">
<input type="Text" value={firstName} onChange={() => setFirstName(e.target.value)}></input>
<input type="Text" value={lastName} onChange={() => setLastName(e.target.value)}></input>
<h1> hello {firstName} {lastName} </h1>
</div>
);
}
<input type="Text" onChange={ChangeFirst}></input>
<input type="Text" onChange={ChangeLast}></input>
use two states
const [firstName, setFirstName] = useState('')
const [lastName, setLastName] = useState('')
then respectively on your method use the setState for each of them separately
Firstly the setSavedinput is a function and not a variable. It's a function to set the value of the variable used with it. Since you are taking the value from input field the following method might work out for you.
import React, { useState } from "react";
export default function App() {
const [Savedinput, setSavedinput] = useState({Firstname:'' , Lastname:''} );
return (
<div className="App">
<input type="text" value={Savedinput.Firstname} onChange={(e)=>setSavedinput({... Savedinput , Firstname:e.target.value })} />
<input type="text" value={Savedinput.Lastname} onChange={(e)=>setSavedinput({... Savedinput , Lastname:e.target.value })} />
<h1> hello {Firstname} {Lastname} </h1>
</div>
Instead of declaring a function , you can do it inline for this purpose .
Also I would suggest you to keep the variable names in an order. This is gonna you a lot.
You can use this for the object and ...savedinput to maintain the existing object with updating only changed value
export default function App() {
const [savedinput, setSavedinput] = useState({firstname:"",
lastname:""});
function ChangeFirst (e) {
savedinput.firstname = e
setSavedinput({...savedinput})
};
function ChangeLast(e) {
savedinput.lastname = e
setSavedinput({...savedinput})
};
return (
<div className="App">
<input type="Text" onChange={event =>
ChangeFirst(event.target.value)}></input>
<input type="Text" onChange={event =>
ChangeLast(event.target.value)}>.
</input>
<h1> hello {savedinput.firstname }{savedinput.lastname} </h1>
</div>
);
}
You can find this working in this link

How to display the state on the same page when clicked Submit button in react

I have made a form in react which takes input from the user and stores it in the state. Now, I want to display the state values when the user clicks Submit button in an input field just below the submit button in React.
Im new to react.
You have to make an object (E.g. Credentials) and when someone clicks the button, credential takes the props of the state like this:
App.js
//import code....
import Form from './Form.js'
//class app code.....
//in the render method:
render() {
return (
<Form />
)
}
Form.js
// import code ....
state = {
firstName: '', // or what you want
lastName: '', // or what you want
email: '', // or what you want
send: false,
}
//handleChange function
const handleChange = (event) => {
const {name, value} = event.target
this.setState({
[name]: value
})
}
//handleClick function
const handleClick = () => {
this.setState({send: true})
}
In the Render method
render() {
return (
<div>
<input name='firstName' onChange={handleChange} />
<input name='lastName' onChange={handleChange} />
<input name='email' onChange={handleChange}/>
<button onClick={handleClick}>Send</button>
{send &&
<Credentials
firstName={this.state.firstName}
lastName={this.state.lastName}
email={this.state.email}
/>
}
</div>
)
}
export default Form // or your file's name
In the Credential.js
//import code...
const Credentials = ({firstName, lastName, email}) => {
return (
<h2>firstName is: {firstName}</h2>
<h4>lastName is: {lastName}</h4>
<p>email is: {email}</p>
)
}
export default Credentials
In React you can use 'useState' to initiate a number or any kind of input. Then set that number when the user clicks on a button.
import React, { useState } from "react";
function App() {
const [number, setNumber] = useState();
let typedNumber = 0;
const btnHandler = (e) => {
e.preventDefault();
setNumber(typedNumber);
};
return (
<div>
<form onSubmit={btnHandler}>
<input type="text" onChange={(e) => (typedNumber = e.target.value)} />
<input type="submit" />
</form>
<p>{number}</p>
</div>
);
}
export default App;

Categories

Resources