একটি HTML input সাধারণত নিজের মান নিজে ভেতরে ভেতরে ম্যানেজ করে। React-এ, প্রচলিত প্যাটার্ন — একটি controlled input — এর বদলে state-কে একমাত্র সোর্স অফ ট্রুথ বানায়, ইনপুট শুধু state যা বলে তাই দেখায়।
function NameForm() {
const [name, setName] = useState('');
return (
<input
value={name}
onChange={(e) => setName(e.target.value)}
/>
);
}প্রতিটি কীস্ট্রোক onChange ফায়ার করে, যা state আপডেট করে, যা নতুন মান দিয়ে ইনপুট re-render করে — দৃশ্যত তাৎক্ষণিক, কিন্তু এটা প্রতিবার সত্যিকারভাবে state-এর মধ্য দিয়ে একটি round trip, ব্রাউজারের নিজস্ব ডিফল্ট টাইপিং আচরণ নয়।
value আসলেই কাজ করতে onChange দরকার
একটি onChange হ্যান্ডলার ছাড়া value সেট করলে ইনপুট স্থায়ীভাবে সেই মানে আটকে যায় — টাইপ করলে কিছু হয় না, কারণ value নিয়ন্ত্রণ করা state কখনো আপডেট হয় না। Controlled ইনপুটের সবচেয়ে সাধারণ শুরুর ভুলগুলোর একটি এটি।
function NameForm() {
const [name, setName] = useState('');
function handleSubmit(e) {
e.preventDefault(); // stop the browser's default full-page reload
console.log('Submitted:', name);
}
return (
<form onSubmit={handleSubmit}>
<input value={name} onChange={(e) => setName(e.target.value)} />
<button type="submit">Submit</button>
</form>
);
}সব ফিল্ডসহ একটি useState অবজেক্ট, ফিল্ডের নাম দিয়ে আপডেট করা, একটি ফর্ম এক-দুইটি ইনপুটের বেশি বড় হয়ে গেলে প্রচলিত প্যাটার্ন:
function SignupForm() {
const [formData, setFormData] = useState({ name: '', email: '' });
function handleChange(e) {
const { name, value } = e.target;
setFormData({ ...formData, [name]: value }); // computed property name, from ES6
}
return (
<form>
<input name="name" value={formData.name} onChange={handleChange} />
<input name="email" value={formData.email} onChange={handleChange} />
</form>
);
}{ ...formData, [name]: value } ঠিক আগের পাঠের immutable-আপডেট প্যাটার্ন — একটি নতুন অবজেক্ট, একটি ফিল্ড বদলানো, কোন key ডাইনামিকভাবে আপডেট হবে তা বেছে নিতে name অ্যাট্রিবিউট ব্যবহার করে।
function Preferences() {
const [subscribed, setSubscribed] = useState(false);
return (
<input
type="checkbox"
checked={subscribed}
onChange={(e) => setSubscribed(e.target.checked)} // checked, not value
/>
);
}