I'm new to react and learn it through a tutorial about ethereum. Here is how the form with multiple fields is created
const Input = ({ placeholder, name, type, value, handleChange }) => (
<input
placeholder={placeholder}
type={type}
step="0.0001"
value={value}
onChange={(e) => handleChange(e, name)}
className="noTailwind"
/>
);
<Input placeholder="address to" name="addressTo" type="text" handleChange={handleChange} />
<Input placeholder="Amount (ETH)" name="amount" type="text" handleChange={handleChange} />
<Input placeholder="Keyword (Gif)" name="keyword" type="text" handleChange={handleChange} />
<Input placeholder="Enter message" name="message" type="text" handleChange={handleChange} />
Then handleChange
is called in TransactionContext.jsx
:
const [formData, setformData] = useState({ addressTo: "", amount: "", keyword: "", message: "" });
const handleChange = (e, name) => {
console.log('handling change:', name, e.target.value);
setformData((prevState) => ({ ...prevState, [name]: e.target.value }));
};
When I type in the form I see the first letter (keypress) appears in the console, but nothing is shown in the form and other key pressess are not registered.
I seem in the console messages like handling change: amount g
and that's all
I'm wondering what is wrong and how can I fix it?
CodePudding user response:
You aren't passing a value to the Input
s:
<Input placeholder="address to" name="addressTo" type="text" handleChange={handleChange} />
So in
const Input = ({ placeholder, name, type, value, handleChange }) => (
the value
prop is undefined
.
Pass down the form data, and then access the [name]
property on it.
Your handleChange
function is also broken, because it tries to access the React event handler after the asynchronous state setter function gets called - React synthetic events should only be directly accessed synchronously.
Live demo:
const Input = ({ placeholder, name, type, formData, setformData }) => {
return <input
placeholder={placeholder}
type={type}
step="0.0001"
value={formData[name]}
onChange={(e) => { setformData({ ...formData, [name]: e.currentTarget.value }) }}
className="noTailwind"
/>
};
const App = () => {
const [formData, setformData] = React.useState({ addressTo: "", amount: "", keyword: "", message: "" });
return <Input placeholder="address to" name="addressTo" type="text" {...{ formData, setformData }} />
};
ReactDOM.render(<App />, document.querySelector('.react'));
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<div class='react'></div>
CodePudding user response:
pass in a value on the input tag
<Input placeholder="address to" name="addressTo" type="text" handleChange={handleChange} />
to
<Input placeholder="address to" name="addressTo" value = {value} type="text" handleChange={handleChange} />