ترفندهای طلایی ری اکت با مثال های کاربردی – بخش اول

با عرض سلام خدمت همراهان همیشگی آکادمی راهکارینو. آنچه که در ادامه می بینید مجموعه مقالات آموزشی [ترفندهای طلایی ری اکت] می باشد. این مجموعه از سه بخش تقسیم شده که هر بخش شامل ۲۰ ترفند ReactJS با مثال کاربردی است. موضوعاتی از قبیل:
- کار با Cookie در ریکت
- نمایش تاریخ و زمان فعلی
- تعریف مقدار پیش فرض برای props
- خواندن فایل json و نمایش آن در صفحه
- تعریف عنوان صفحه در ریکت
- تعریف داینامیک تصویر favicon
- نحوه ارسال درخواست post
- و…
در این پست با بخش اول از نکات و ترفندهای طلایی ری اکت در خدمت شما هستیم.
1- نحوه کار با cookie در ریکت:
چگونه می توانیم کوکی های ثبت شده در مرورگر را در اپلیکیشن های ریکت دریافت کنیم و یا یک کوکی جدید ثبت کنیم؟ با استفاده از پکیج react-cookie
برای نصب پکیج react-cookie دستور زیر را اجرا کنید:
npm install react-cookie
سپس باید کامپوننت cookiesProvider را از کتابخانه react-cookie ایمپورت کنید و کامپوننت App را درون آن قرار دهید:
import React from "react"; import ReactDOM from "react-dom"; import { CookiesProvider } from "react-cookie"; import App from "./App"; const rootElement = document.getElementById("root"); ReactDOM.render( <CookiesProvider> <App /> </CookiesProvider>, rootElement );
حالا هر جا که می خواهید کوکی مرورگر را دریافت کنید، براحتی می توانید از هوک useCookies استفاده کنید. بعنوان مثال در فانکشنال کامپوننت ها داریم:
import React from "react"; import ReactDOM from "react-dom"; import { CookiesProvider } from "react-cookie"; import App from "./App"; const rootElement = document.getElementById("root"); ReactDOM.render( <CookiesProvider> <App /> </CookiesProvider>, rootElement );
و در کلاس کامپوننت ها باید withCookies را از کتابخانه react-cookie ایمپورت کنید:
import React, { Component } from "react"; import { withCookies } from "react-cookie"; class App extends Component { state = { // getting the cookie user: this.props.cookies.get("user") || "" }; render() { const { user } = this.state; return ( <div className="App"> {user && <p>{user}</p>} </div> ); } } export default withCookies(App);
2- باز کردن لینک در تب جدید مرورگر:
در تگ لینک HTML براحتی می توان با اتریبیوت target=’_blank’ یک لینک را در تب جدید مرورگر باز کرد. اما اگر بخواهیم بوسیله برنامه نویسی و رویداد onClick اینکار را انجام دهیم از window.open استفاده خواهیم کرد:
import React from "react"; function App() { const handleClick = () => { window.open("http://twitter.com/saigowthamr"); }; return ( <div> <h2>App</h2> <button onClick={handleClick}>Twitter</button> </div> ); } export default App;
3- غیرفعال کردن autoComplete در input:
به منظور غیرفعال کردن autoComplete در یک input مشخص، کافیست اتریبیوت autocomplete را برابر off قرار داد:
import React from "react"; export default function App() { return ( <div className="App"> <input type="text" autoComplete="off"/> </div> ); }
اما اگر بخواهید در تمام فیلدهای فرم این قابلیت غیرفعال شود، خواهیم داشت:
import React from "react"; export default function App() { return ( <div className="App"> <form autoComplete="off"> <input type="text"/> </form> </div> ); }
با غیرفعال کردن autoComplete به مرورگر می گوییم “لطفا داده های ورودی کاربران را ذخیره نکن!”
4- نحوه نمایش تاریخ روز جاری در ریکت:
توسط متد سازنده ()new Date می توان به تاریخ فعلی دسترسی داشت. new Date سه متد در اختیار ما قرار می دهد:
- ()getDate: چندمین روز ماه را برمی گرداند. مثلا اگر امروز 22 مرداد باشد، عدد 22 را برمی گرداند.
- ()getMonth: چندمین ماه سال را برمی گرداند. ماه ژانویه عدد 0 و ماه دسامبر عدد 11 را برمی گرداند.
- ()getFullYear: سال جاری را با فرمت چهار رقمی بر می گرداند.
بعنوان مثال:
import React from "react"; export default function App() { const current = new Date(); const date = `${current.getDate()}/${current.getMonth()+1}/${current.getFullYear()}`; return ( <div className="App"> <h1>Current date is {date}</h1> </div> ); }
خروجی:
5- نحوه دریافت پارامترهای کوئری از URL:
پارامترهای کوئری (Query Params) به عبارتی گفته می شود که در انتهای url و پس از علامت سوال ؟ قرار می گیرد و بصورت key=value است. بعنوان مثال:
localhost:3000/items?name=pen
برای دریافت پارامترهای کوئری در نسخه 4 به بعد react-router از props.location.search استفاده می کنیم. بعنوان مثال در فانکشن کامپوننت:
import React from 'react'; export default function Items(props) { const search = props.location.search; const name = new URLSearchParams(search).get('name'); return ( <div> <h1>Items page</h1> <p>{name}</p> </div> ); }
و در کلاس کامپوننت:
import React, { Component } from "react"; class Items extends Component { render() { const search = this.props.location.search; const name = new URLSearchParams(search).get("name"); return ( <div> <h1>Items page</h1> <p>{name}</p> </div> ); } } export default Items;
6- نحوه استفاده از متغیرهای environment:
متغیرهای محیطی (environment variables) به توسعه دهنده کمک می کند تا تنظیمات مختلفی را در اپلیکیشن خود تعریف کند. بعنوان مثال آدرس های API متفاوتی برای زمان development یا توسعه و زمان production یا محصول.
برای شروع کار با این متغیرها، یک فایل بدون نام و با فرمت env. در روت پروژه ایجاد کنید. حالا در این فایل می توان با ساختار REACT_APP_.VARIABLE_NAME=VALUE متغیرهای محیطی موردنظر را تعریف کرد. بعنوان مثال:
REACT_APP_.BASE_URL=https://google.com
نکته امنیتی: در صورتی که متغیرهای محرمانه و امنیتی (مانند پسورد) در این فایل ذخیره شده است، مراقب باشید که فایل env. را در گیت commit نکنید و از gitignore استفاده کنید.
برای دسترسی به متغیرهای ENV باید عبارت process.env را قبل از نام متغیر محیطی درج کرد. مثلا:
import React from "react"; export default function App(){ return ( <div> <a href={process.REACT_APP_.BASE_URL}>My app</a> </div> ) }
اگر می خواهیم در فایل index.html اپلیکیشن از این متغیرها استفاده کنید باید به شکل زیر تعریف کنید:
<base href="%REACT_APP_BASE_URL%">
7- نحوه تعریف مقدار پیش فرض props:
برای درنظر گرفتن یک مقدار پیش فرض برای props باید props موردنظر را در آبجکت defaultProps تعریف کرد و مقدار دلخواه را تعریف کرد. مثلا:
فایل Welcome.js:
import React from "react"; export default function Welcome(props){ return <h1>Welcome {props.name}</h1> } // setting default value to name prop Welcome.defaultProps = { name: "Boss" }
فایل App.js:
import React from "React"; import Welcome from "./Welcome"; export default function App() { return ( <div> <Welcome /> <p>My first react app</p> </div> ); }
مشاهده می شود که هنگام استفاده از کامپوننت Welcome هیچ props ای ارسال نکرده ایم. اما در کامپوننت Welcome یک مقدار پیش فرض برای name تعریف شده است. پس از همین مقدار استفاده خواهد شد.
8- مشاهده سریع نسخه ری اکت:
برای مشاهده نسخه ریکتی که در پروژه در حال استفاده است، درون یک کامپوننت به شکل زیر عمل می کنیم:
import React from "react"; import "./styles.css"; export default function App() { return ( <div className="App"> <h1>Current version is {React.version}</h1> </div> ); }
و اگر می خواهیم درون ترمینال، نسخه ریکت را مشاهده کنیم، دستور زیر را باید تعریف کرد:
npm list react
روش بعدی، مشاهده ورژن ریکت نصب شده از فایل package.json می باشد:
{ "name": "react", "version": "1.0.0", "description": "React Tips by Rahkarino Academy", "keywords": [ "react", "starter" ], "main": "src/index.js", "dependencies": { "react": "17.0.2", "react-dom": "17.0.2",
9- نحوه استفاده از فایل JSON در ریکت:
برای لود دیتای داخل فایل جیسون (JSON) و نمایش آن در UI داریم:
فرض کنید فایل users.json شامل محتوای زیر باشد:
[ { "id": 1, "name": "John" }, { "id": 2, "name": "Pen" }, { "id": 3, "name": "Lara" } ]
حالا می خواهیم فایل فوق را در کامپوننت موردنظر خود لود کنیم و در مرورگر نمایش دهیم. کد زیر را باید تعریف کرد:
import React from "react"; import Users from "./users.json"; export default function App() { return ( <div className="App"> <h1>Users list</h1> {Users.map(user => ( <li key={user.id}>{user.name}</li> ))} </div> ); }
در کد فوق، ابتدا فایل json به کامپوننت import شده است و سپس در یک حلقه map داده های داخل آن را نمایش می دهیم.
10- دریافت مسیر جاری در ریکت روتر:
می خواهیم نحوه دریافت مسیر (path) جاری را از url در ریکت آموزش دهیم.
در فانکشن کامپوننت:
import React from "react"; import { useLocation } from "react-router-dom"; export default function About() { const location = useLocation(); console.log(location.pathname); // path is /contact return ( <div> <h2>Contact</h2> </div> ); }
با استفاده از هوک useLocation می توانیم route جاری را بدست آوریم.
در کلاس کامپوننت:
import React from "react"; class About extends React.Component { render() { console.log(this.props.location.pathname); // path is /about return ( <div> <h2>About</h2> </div> ); } } export default About;
11- فعال سازی رویداد onClick با Enter:
در این بخش می خواهیم نحوه فعال سازی button click را با زدن دکمه Enter صفحه کلید آموزش دهیم.
فرض کنید یک فرم جستجو داریم که شامل یک input text و یک button است. می خواهیم وقتی کاربر عبارت موردنظر خود را در input تایپ کرد و دکمه Enter را زد، جستجو فعال شود. یعنی رویداد oClick دکمه trigger شود.
import React, { useState } from "react"; export default function App() { const [value, setValue] = useState(""); const handleChange = e => { setValue(e.target.value); }; const handleSubmit = e => { e.preventDefault(); alert("you have searched for - " + value); // or you can send to backend }; return ( <div className="App"> <form> <input value={value} onChange={handleChange}/> <button onClick={handleSubmit} type="submit"> Submit </button> </form> </div> ); }
در کد بالا فقط با کلیک روی دکمه جستجو، عملیات سرچ انجام می شود اما همانطور که گفتیم ما می خواهیم با کلید Enter هم سرچ انجام شود.
می خواهیم اینکار را توسط رویداد onKeypress انجام دهیم. این رویداد زمانی رخ می دهد که کاربر یک دکمه از صفحه کلید را بزند. در یک شرط بررسی می کنیم که آیا کاربر روی دکمه Enter کلیک کرده است یا خیر.
import React, { useState } from "react"; export default function App() { const [value, setValue] = useState(""); const handleChange = e => { setValue(e.target.value); }; const handleSubmit = e => { e.preventDefault(); alert("you have searched for - " + value); // or you can send data to backend }; const handleKeypress = e => { //it triggers by pressing the enter key if (e.keyCode === 13) { handleSubmit(); } }; return ( <div className="App"> <form> <input value={value} onChange={handleChange} onKeyPress={handleKeypress} /> <button onClick={handleSubmit} type="submit"> Submit </button> </form> </div> ); }
در کد بالا، گفتیم که اگر keyCode دکمه زده شده است، متد مربوط به سرچ فراخوانی شود.
12- تعریف کردن عنوان داکیومنت در ریکت:
در این بخش می خواهیم نحوه تعریف عنوان را برای صفحات اپلیکیشن در ری اکت آموزش دهیم.
در فانکشن کامپوننت:
بوسیله هوک useDocTitle می توان برای صفحات اپ ری اکت، عنوان منحصربفرد تعریف کرد. به روش زیر:
import React from "react"; import {useDocTitle} from "customHooks" export default function App() { const [doctitle, setDocTitle] = useDocTitle("Home page"); return ( <div className="App"> <h1>Hello React</h1> {/* changing title dynamically */} <button onClick={() => setDocTitle("Home lab")}> Change title </button> </div> ); }
در کلاس کامپوننت:
اما در class component، می توان از متد لایف سایکل componentDidMount برای تعریف تایتل صفحه استفاده کرد:
import React from "react"; class App extends React.Component { componentDidMount() { document.title = "Home Page"; } render() { return ( <div className="App"> <h1>Hello React</h1> </div> ); } } export default App;
13- نحوه تعریف استایل های inline در ریکت:
در این قسمت می خواهیم آموزش دهیم که چگونه می توان چندین استایل درون خطی (inline style) را به یک المان در ریکت نسبت دهیم.
حالت اول (یک آبجکت جاوا اسکریپتی):
می توان استایل های CSS را در قالب آبجکت جاوا اسکریپت، به المان موردنظر نسبت داد. بصورت زیر:
import React from 'react'; const box = { color: "green", fontSize: '23px' } export default function App(){ return ( <div style={box}> <h1>Hello react</h1> </div> ) }
حالت دوم (چندین آبجکت جاوا اسکریپتی):
اگر چندین آبجکت جاوا اسکریپتی برای استایل ها داشته باشیم، به روش زیر می توان آبجکت ها را ادغام کرد و بعنوان استایل المان در نظر گرفت:
import React from 'react'; const box = { color: "green", fontSize: '23px' } const shadow = { background: "orange", boxShadow: "1px 1px 1px 1px #cccd" } export default function App(){ return ( <div style={{...box, ...shadow}}> <h1>Hello react</h1> </div> ) }
در کد بالا، توسط عملگر spread در جاوا اسکریپت، چند آبجکت مختلف را با هم ترکیب کرده ایم و بعنوان استایل المان درنظر گرفته ایم.
14- نحوه تعریف داینامیک Favicon:
پروژه را در یک ادیتور مانند VS-Code باز کنید و به پوشه public رفته و فایل index.html را باز کنید. بدنبال تگ زیر در این فایل بگردید و اتریبیوت id را به آن اضافه کنید:
<link rel="shortcut icon" id="favicon" href="%PUBLIC_URL%/favicon.ico">
اکنون می توانیم در فایل App.js توسط document.getElementById به این تگ دسترسی داشته باشیم. در واقع باید اتریبیوت href تگ favicon را تغییر دهیم:
import React from "react"; function getFaviconEl() { return document.getElementById("favicon"); } function App() { const handleGoogle = () => { const favicon = getFaviconEl(); // Accessing favicon element favicon.href = "https://www.google.com/favicon.ico"; }; const handleYoutube = () => { const favicon = getFaviconEl(); favicon.href = " https://s.ytimg.com/yts/img/favicon-vfl8qSV2F.ico"; }; return ( <div className="App"> <h1>Dynamically changing favicon</h1> <button onClick={handleGoogle}>Google</button> <button onClick={handleYoutube}>YouTube</button> </div> ); } export default App;
در قطعه کد بالا، دو تا دکمه داریم که با کلیک روی Google، فاوآیکون اپلیکیشن به Google تغییر پیدا می کند و با کلیک روی Youtube آیکون برنامه به Youtube آپدیت می شود.
15- نحوه تعریف شرطی نام کلاس CSS:
ممکن است گاهی مواقع بخواهیم یک کلاس CSS بنا به شرایطی به المان موردنظرمان اضافه گردد. مثلا در کد زیر می خواهیم وقتی isActive برابر true است کلاس shadow به المان div اضافه گردد در غیر اینصورت هیچ کلاسی اضافه نشود.
import React, {useState} from 'react'; import './styles.css'; function App(){ const [isActive, setActive] = useState(false); return ( <div className={`container top-3 ${isActive ? "shadow": ""}`}> <h1>Hello rock!!</h1> <button onClick = {()=>setActive(!isActive)}> change classname </button> </div> ) } export default App;
به همین ترتیب می توان برای زمانی که isActive برابر false است یک کلاس دیگر به المان اضافه کنیم:
<div className={`container top-3 ${isActive ? "shadow": "red-shadow"}`}>
16- نحوه disable کردن دکمه بصورت شرطی:
در پروژه های واقعی گاهی پیش می آید که می خواهیم بر اساس شرایطی دکمه فرم غیرفعال (disabled) باشد. فرض کنید در فرم لاگین، تا زمانیکه کاربر نام کاربری و رمز عبور را پر نکرده است، دکمه لاگین غیر فعال باشد. در مثال زیر گفتیم تا زمانی که مقدار input جستجو خالی است دکمه Search غیرفعال باشد:
import React, {useState} from "react"; function App() { const [name, setName] = useState(''); const nameChange = e => setName(e.target.value); return ( <div className="App"> <input value={name} onChange={nameChange} placeholder="Name"/> <button disabled={!name}>Search</button> </div> ); } export default App;
17- نحوه ارسال درخواست POST به سرور توسط هوک:
زمانی که بخواهیم اطلاعات یک فرم را به سرور POST کنیم، می توان اطلاعات فرم را در state ذخیره کرد و از متد fetch برای ارسال آنها استفاده کرد. در مثال زیر، مقادیر دو فیلد title و body را داخل state ذخیره می کنیم و سپس توسط fetch آنها را به سرور ارسال می کنیم.
import React, { useState } from "react"; function App() { const [title, setTitle] = useState(""); const [body, setBody] = useState(""); const onTitleChange = e => setTitle(e.target.value); const onBodyChange = e => setBody(e.target.value); const handleSubmit = e => { e.preventDefault(); const data = { title, body }; const requestOptions = { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(data) }; fetch("https://jsonplaceholder.typicode.com/posts", requestOptions) .then(response => response.json()) .then(res => console.log(res)); }; return ( <div className="App"> <form> <input placeholder="Title" value={title} onChange={onTitleChange} required /> <textarea placeholder="Body" value={body} onChange={onBodyChange} required /> <button type="submit" onClick={handleSubmit}> Create Post </button> </form> </div> ); } export default App;
در مثال بالا، وقتی روی دکمه Create Post کلیک می شود، متد handleSubmit اجرا می شود و در آن مقادیر title و body از state گرفته می شود و api call به سرور انجام می شود.
18- نحوه اجرای رویداد onClick به همراه پارامتر:
در ری اکت می توان با استفاده از arrow function ها، پارامترهای دلخواه را به رویداد onClick دکمه ارسال کرد. کد زیر را در نظر بگیرید:
function Welcome() { const checkOut = (name) => { alert(`Hello ${name}`); } return ( <div> <button onClick={() => checkOut('Gowtham')}>Greet</button> </div> ) } export default Welcome;
اما چگونه می توانیم هر دوی event و پارامتر را پاس دهیم؟ به صورت زیر:
function Welcome() { const checkOut = (e, name) => { e.preventDefault(); alert(`Hello ${name}`); } return ( <div> <button onClick={() => checkOut(e,'Gowtham')}>Greet</button> </div> ) } export default Welcome;
در کد بالا، هم event را به رویداد onClick پاس داده ایم و هم پارامتر دلخواه را.
19- نحوه افزودن فونت سفارشی در ریکت:
برای افزودن فونت های سفارشی به اپلیکیشن ریکت، ابتدا یک فولدر بنام fonts در مسیر src ایجاد کنید و سپس فایل های مربوط به فونت دلخواه تان را داخل این فولدر بریزید. سپس فایل index.css را باز کرده و کد زیر را تعریف کنید:
@font-face { font-family: 'RahkarinoFont'; src: url('webfont.eot'); /* IE9 Compat Modes */ src: url('webfont.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */ url('webfont.woff2') format('woff2'), /* Super Modern Browsers */ url('webfont.woff') format('woff'), /* Pretty Modern Browsers */ url('webfont.ttf') format('truetype'), /* Safari, Android, iOS */ url('webfont.svg#svgFontName') format('svg'); /* Legacy iOS */ }
اکنون می توان از فونتی که در بالا تعریف کردیم در کامپوننت موردنظرمان استفاده کنیم:
.title{ font-family: RahkarinoFont, serif; color: #0004; }
اگر می خواهیم فونت انگلیسی استفاده کنیم، می توان از گوگل فونت هم استفاده کرد.
@import url('https://fonts.googleapis.com/css2?family=Rajdhani:wght@300;500&display=swap');
علاوه بر روش فوق، می توان در فایل index.html نیز فونت موردنظر را اضافه کرد:
<link href="https://fonts.googleapis.com/css2?family=Rajdhani:wght@300;500&display=swap" rel="stylesheet">
20- نحوه نمایش Loading در ریکت:
فرض کنید می خواهیم وقتی اپلیکیشن در حال دریافت داده ها از سرور است، یک لودینگ به کاربر نمایش دهیم. برای اینکار تصویر متحرک (gif) مربوط به لودینگ را دانلود کرده و در فولدر images پروژه قرار می دهیم. فرضا تصویر زیر:
سپس در فایل کامپوننت موردنظر، آن را import می کنیم:
import LoadingImage from './images/loading.gif'
در مرحله بعد، یک state برای نمایش یا عدم نمایش loading تعریف می کنیم که نوع آن بولین است:
const [loading, setLoading] = useState(false);
سپس باید در متد لایف سایکل useEffect، دستور مربوط به دریافت داده از سرور (GET) را تعریف کنیم. کد زیر را داریم:
useEffect(() => { setLoading(true); axios .get("https://jsonplaceholder.typicode.com/posts") .then((res) => {setLoading(false);}) .catch((err) => {setLoading(false);}); }, []);
در کد بالا تعریف کردیم که به محض لود شدن کامپوننت، تصویر Loading نمایش یابد و پس از دریافت داده از سرور (then یا catch) لودینگ مخفی شود. حالا نحوه استفاده از تصویر لودینگ در JSX به شکل زیر است:
{loading ? <img src={LoadingImage} /> : <div className="App"></div>}
در کد بالا گفتیم اگر مقدار loading برابر true بود، تصویر gif نمایش یابد در غیر اینصورت، خود کامپوننت نمایش پیدا کند. به همین راحتی!
بخش اول از ترفندهای طلایی ری اکت در اینجا به پایان می رسد. در بخش دوم، 20 ترفند و نکته دیگر در ReactJS را بررسی خواهیم کرد.
دیدگاهتان را بنویسید