I'm new to React and I'm stuck with something.
I have 3 components, Home, UserForm and Input, they're nested as described. I need to have the values of the input as the user types on the home component. I can't get it to work.
I need help!
home.jsx
import React from 'react';
import UserForm from '../components/UserForm';
import './Home.scss';
export default function Home() {
return (
<div className="home-container">
<div className="card-container">
</div>
<div className="description-container">
<div className="form-container">
<UserForm />
</div>
</div>
</div>
)
}
UserForm.jsx
import React from 'react';
import Input from './Input';
export default function UserForm(props) {
return (
<div className="user-form">
<form>
<Input
placeholder="Nome a ser impresso" />
<Input placeholder="E-mail" type="email" />
</form>
</div>
)
}
Input.jsx
import React, { useState } from 'react';
import './Input.scss';
export default function Input(props) {
const [inputVal, setInputVal] = useState('');
function listenToInput(e) {
setInputVal(e.target.value);
}
return (
<div className="input-holder">
<input
type={props.type || 'text'}
placeholder={props.placeholder}
value={inputVal}
onChange={listenToInput}/>
</div>
)
}
CodePudding user response:
Move
const [inputVal, setInputVal] = useState('');
To Home
and pass inputVal
and setInputVal
all the way to Input
as props.
This is called "prop drilling".
CodePudding user response:
Like @Gabriel Pichot said in comment: Refer to Lifting State Up
Use component's props to set input's value
if you need mutate state in your Home
component, you can move your state from Input
to Home
.
Then give the props to the UserForm
, and give props again to Input
a example for how to do it:
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
<div id="root"></div>
<script type="text/babel">
// const ThemeContext = React.createContext(themes.light);
function Home() {
const [inputVal, setInputVal] = React.useState('');
const [inputVal2, setInputVal2] = React.useState('');
return (
<div className="home-container">
<div className="card-container">
</div>
<div className="description-container">
<div className="form-container">
<UserForm setInputVal={setInputVal} setInputVal2={setInputVal2} />
</div>
</div>
<p>first input: {inputVal}</p>
<p>second input: {inputVal2}</p>
</div>
)
}
function UserForm(props) {
return (
<div className="user-form">
<form>
<Input
placeholder="Nome a ser impresso" setInputVal={props.setInputVal} />
<Input placeholder="E-mail" type="email" setInputVal={props.setInputVal2} />
</form>
</div>
)
}
function Input(props) {
function listenToInput(e) {
props.setInputVal(e.target.value);
}
return (
<div className="input-holder">
<input
type={props.type || 'text'}
placeholder={props.placeholder}
onChange={listenToInput} />
</div>
)
}
</script>
<script type="text/babel">
ReactDOM.render(
<Home></Home>
, document.getElementById("root"));
</script>
Other ways (React.useContext
)
Or you can use useContext, it can give your state and setState function to the grandchildren component