در این مقاله به چگونگی گرفتن و ویرایش داده و استفاده کردن آن در DOM می پردازیم. برای خیلی از تازه کار ها ممکن است کار با داده های مختلف در Input ها مشکل و دشوار باشد. برای مثال برای ساخت یک TodoApp یا چیزی مشابه آن شما نیاز دارید که داده ها را با استفاده از تگ Input بگیرید و در صورت نیاز اجازه دسترسی به ویرایش آن را به کاربر بدهید. با ویرایش داده باید متنی که نمایش داده می شود هم تغییر کند. ما در این مقاله به تمامی این موضوعات اشاره کرده و آن ها را مورد بررسی قرار می دهیم.
۱- ساخت Input های مورد نیاز در ری اکت:
گام اول ساخت Input ها برای شروع کار است.
فایل App.js:
import { IoIosSend } from "react-icons/io";
function App() {
return (
<div className="parent">
<div className="input-parent">
<input className="input-1" />
<button className="send-btn">
Send
<IoIosSend />
</button>
</div>
<div className="text">
<h2>There is going to be text here!</h2>
</div>
</div>
);
}
export default App;
فایل index.css:
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
background-color: #333;
}
.parent {
padding: 1rem;
margin: 0 auto;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
input {
padding: 0.3rem;
border: none;
border-radius: 0.5rem;
}
.input-parent {
margin-top: 3rem;
display: flex;
gap: 0.5rem;
margin-bottom: 2rem;
}
.send-btn {
padding: 0.5rem 0.75rem;
border-radius: 0.5rem;
border: none;
font-size: 1rem;
display: flex;
align-items: center;
gap: 5px;
cursor: pointer;
}
.text {
background-color: #555;
width: 30rem;
height: 12rem;
padding: 1rem;
color: white;
font-family: "Franklin Gothic Medium", "Arial Narrow", Arial, sans-serif;
display: flex;
justify-content: center;
align-items: center;
border-radius: 1rem;
}
همینطور که در کد مشخص است من یک Input برای گرفتن داده و یک Button برای فرستادن داده دارم (که البته می شود به جای والد div از form استفاده که با کلیک دکمه ی enter داده فرستاده بشود). و البته یک تگ div برای نمایش داده. در این پروژه ی کوچک از React-Icons هم استفاده شده که یک کتابخانه آیکون برای ری اکت است.
۲- گرفتن داده و اتقال و ذخیره ی آن:
حالا باید متنی که کاربر داخل Input می نویسد را بگیریم و آن را جایی ذخیره کنیم. برای ذخیره سازی داده از useState استفاده می کنیم تا داده را در جایی نگه داریم البته که با رفرش کردن صفحه مرور گر مقدار داخل state ما به حالت پیش فرض بر می گردد و ذخیره نمی شود (برای ذخیره داده در کش مرورگر باید از کتابخانه هایی مثل Redux یا Jotai استفاده کنیم). قدم اول اینگونه است. ابتدا استخراج و ساخت state:
import { useState } from "react";
const [data, setData] = useState(""); // داخل فانکشن اصلی قرار دهید
حالا باید برای Input خود یک مقدار onChange قرار دهیم (چرا؟) چون باید بگیم که هر تغییری که داخل Input مورد نظر اتفاق افتاد (یعنی چه کاربر داده ایی را اضافه یا حذف کند) state را به روزرسانی کند و آخرین داده داخل state ذخیره شود. پس مانند کد زیر عمل می کنیم:
<input className="input-1" value={data} onChange={(e) => setData(e.target.value)} />
در کد بالا با استفاده از e.value.target داده ی مورد نظر همان Input را دریافت میکنیم و به فانکشن setData می فرستیم تا داده به روز رسانی شود و value ی Input را هم مساوی state قرار می دهیم.
قدم بعدی تعریف فانکشنی است که به وسیله ی دکمه ی send داده را در لاگ (log) نمایش دهیم (تا مطمعن شویم که داده را فانکشن دریافت می کند).
button مانند زیر می شود:
<button className="send-btn" onClick={dataHandler}>
و فانکشن هم به این شکل:
const dataHandler = function () {
console.log(data);
};
ممکن است بپرسید چرا مستقیم مقدار state که همان data است را داخل تگ h2 ایی که داریم قرار نمی دهیم تا متن نشان داده شود؟ دلیل این کار این است که همزمان و به صورت زنده (Live) با تغییر داده ی داخل Input مقدار متن ما هم عوض می شود اما می خواهیم وقتی دکمه ی send کلیک شد, متن عوض بشود. پس باید یک boolian تعریف کنیم که در صورت کلیک شدن send داده به روز رسانی شود. برای این کار نیاز به یک state دیگر داریم:
const [updtate, setUpdate] = useState(false);
در اینجا یک state تعریف کردیم که مقدار پیش فرض را false قرار دادیم. باید هر وقت که دکمه ی send کلیک شد این state را true قرار بدهیم و هر وقت که کاربر در حال نوشتن بود این state را مساوی false بگذاریم. زیرا قرار است که متن همان data باشد اما همانطور که قبلا توضیح داده شد با هر تغییر, متن هم تغییر می کند. پس این state به ما این اجازه را می دهد که هر وقت که کاربر send را کلیک کرد داده نمایش داده شود.
پس اول فانکشنی که هنگام کلیلک کردن دکمه send صدا زده میشود را به روز رسانی می کنیم:
const dataHandler = function () {
console.log(data);
setUpdate(true);
};
حالا اگر کاربر یک بار دکمه ی send را کلیک کند برای همیشه مقدار update ما true است و ما باید از این اتفاق جلوگیری کنیم. پس هر وقت که کاربر شروع به نوشتن کرد باید مقدار update را false کنیم:
<input
className="input-1"
onChange={(e) => {
setUpdate(false);
setData(e.target.value);
}}
که در اینجا این کار را انجام دادیم. حالا برای نمایش متن باید باید با استفاده از if statement ها مقدار update را چک کنیم:
<div className="text">
<h2>{updtate ? data : "..."}</h2>
</div>
که در اینجا چک می کنیم که اگر update با true برابر بود مقدار دیتا را به ما نمایش بدهد در غیر این صورت به ما "..." نمایش بدهد و تمام.
۳- چرا از e.target.value استفاده می کنیم؟
اگر ما فقط e.target را لاگ بگیریم میبینیم که در قسمت لاگ مرور گر به تگ Input اشاره می کند. یعنی وقتی ما از e.target.value استفاده می کنیم منظورمان این است که مقدار داخل تگ Input را برایمان بر گرداند. ممکن است داخل یک پروژه ی بزرگ تر چندین تگ Input وجود داشته باشد که باید برای هر Input یک state جدا تعریف کنیم و جدا مقدار هرکدام را دریافت و به روز رسانی کنیم.