உங்கள் சில components React-க்கு வெளியே உள்ள systems-ஐ control செய்து அவற்றுடன் synchronize செய்ய வேண்டியிருக்கும். உதாரணமாக, browser API பயன்படுத்தி input-ஐ focus செய்ய வேண்டியிருக்கலாம், React இல்லாமல் implemented செய்யப்பட்ட video player-ஐ play மற்றும் pause செய்ய வேண்டியிருக்கலாம், அல்லது remote server-இலிருந்து messages-ஐ connect செய்து listen செய்ய வேண்டியிருக்கலாம். இந்த chapter-இல், React-க்கு “வெளியே செல்ல” மற்றும் external systems-க்கு connect செய்ய உதவும் escape hatches-ஐ கற்றுக்கொள்வீர்கள். உங்கள் application logic மற்றும் data flow-ன் பெரும்பகுதி இந்த features-ஐ சார்ந்து இருக்கக்கூடாது.
இந்த அத்தியாயத்தில் நீங்கள் கற்றுக்கொள்ள போவது
- Re-render செய்யாமல் தகவலை “நினைவில்” வைத்திருப்பது எப்படி
- React manage செய்யும் DOM elements-ஐ access செய்வது எப்படி
- Components-ஐ external systems-உடன் synchronize செய்வது எப்படி
- உங்கள் components-இலிருந்து தேவையற்ற Effects-ஐ remove செய்வது எப்படி
- Effect-ன் lifecycle component-ன் lifecycle-இலிருந்து எப்படி வேறுபடுகிறது
- சில values Effects-ஐ மீண்டும் trigger செய்வதைத் தடுப்பது எப்படி
- உங்கள் Effect குறைவாக re-run ஆக செய்வது எப்படி
- Components இடையே logic பகிர்வது எப்படி
Refs மூலம் values-ஐ reference செய்தல்
ஒரு component சில தகவலை “நினைவில்” வைத்திருக்க வேண்டும், ஆனால் அந்த தகவல் புதிய renders-ஐ trigger செய்ய வேண்டாம் என்றால், ref ஒன்றைப் பயன்படுத்தலாம்:
const ref = useRef(0);State போலவே, refs re-renders இடையே React-ஆல் retained ஆகின்றன. ஆனால் state set செய்தால் component re-render ஆகும். Ref மாற்றினால் re-render ஆகாது! அந்த ref-ன் current value-ஐ ref.current property மூலம் access செய்யலாம்.
import { useRef } from 'react'; export default function Counter() { let ref = useRef(0); function handleClick() { ref.current = ref.current + 1; alert('நீங்கள் ' + ref.current + ' முறை click செய்தீர்கள்!'); } return ( <button onClick={handleClick}> என்னை click செய்! </button> ); }
Ref என்பது React track செய்யாத உங்கள் component-ன் ரகசிய பையில் இருப்பது போன்றது. உதாரணமாக, component-ன் rendering output-ஐ பாதிக்காத timeout IDs, DOM elements, மற்றும் பிற objects-ஐ store செய்ய refs பயன்படுத்தலாம்.
Ready to learn this topic?
தகவலை நினைவில் வைத்திருக்க refs-ஐ எப்படி பயன்படுத்துவது என்பதை அறிய Referencing Values with Refs-ஐ படியுங்கள்.
Read MoreRefs மூலம் DOM-ஐ manipulate செய்தல்
உங்கள் render output-க்கு match ஆக DOM-ஐ React தானாக update செய்கிறது, எனவே உங்கள் components அதை அடிக்கடி manipulate செய்யத் தேவையில்லை. ஆனால் சில நேரங்களில் React manage செய்யும் DOM elements-க்கு access தேவைப்படலாம்—உதாரணமாக node ஒன்றை focus செய்ய, அதற்கு scroll செய்ய, அல்லது அதன் size மற்றும் position-ஐ measure செய்ய. React-இல் இவற்றுக்கான built-in வழி இல்லை, எனவே DOM node-க்கு ref தேவைப்படும். உதாரணமாக, button-ஐ click செய்தால் ref பயன்படுத்தி input focus செய்யப்படும்:
import { useRef } from 'react'; export default function Form() { const inputRef = useRef(null); function handleClick() { inputRef.current.focus(); } return ( <> <input ref={inputRef} /> <button onClick={handleClick}> Input-ஐ focus செய் </button> </> ); }
Ready to learn this topic?
React manage செய்யும் DOM elements-ஐ access செய்வது எப்படி என்பதை அறிய Manipulating the DOM with Refs-ஐ படியுங்கள்.
Read MoreEffects மூலம் synchronize செய்தல்
சில components external systems-உடன் synchronize செய்ய வேண்டும். உதாரணமாக, React state அடிப்படையில் non-React component ஒன்றை control செய்ய விரும்பலாம், server connection அமைக்கலாம், அல்லது component screen-இல் தோன்றும்போது analytics log அனுப்பலாம். குறிப்பிட்ட events-ஐ handle செய்ய event handlers உதவுவது போல அல்லாமல், Effects rendering-க்கு பிறகு சில code run செய்ய அனுமதிக்கின்றன. React-க்கு வெளியே உள்ள system-உடன் உங்கள் component-ஐ synchronize செய்ய அவற்றைப் பயன்படுத்துங்கள்.
இயக்கு/இடைநிறுத்து button-ஐ சில முறை அழுத்தி, video player isPlaying prop value-உடன் எப்படி synchronized ஆக இருக்கிறது என்பதைப் பாருங்கள்:
import { useState, useRef, useEffect } from 'react'; function VideoPlayer({ src, isPlaying }) { const ref = useRef(null); useEffect(() => { if (isPlaying) { ref.current.play(); } else { ref.current.pause(); } }, [isPlaying]); return <video ref={ref} src={src} loop playsInline />; } export default function App() { const [isPlaying, setIsPlaying] = useState(false); return ( <> <button onClick={() => setIsPlaying(!isPlaying)}> {isPlaying ? 'இடைநிறுத்து' : 'இயக்கு'} </button> <VideoPlayer isPlaying={isPlaying} src="https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.mp4" /> </> ); }
பல Effects தங்களுக்குப் பிறகு “clean up” செய்கின்றன. உதாரணமாக, chat server-க்கு connection அமைக்கும் Effect, அந்த server-இலிருந்து உங்கள் component-ஐ disconnect செய்வது எப்படி என்று React-க்கு சொல்வதற்கான cleanup function ஒன்றை return செய்ய வேண்டும்:
import { useState, useEffect } from 'react'; import { createConnection } from './chat.js'; export default function ChatRoom() { useEffect(() => { const connection = createConnection(); connection.connect(); return () => connection.disconnect(); }, []); return <h1>Chat-க்கு வரவேற்கிறோம்!</h1>; }
Development-இல், React உங்கள் Effect-ஐ கூடுதலாக ஒருமுறை உடனே run செய்து clean up செய்யும். அதனால்தான் "✅ Connect செய்யப்படுகிறது..." இருமுறை print ஆகிறது. Cleanup function implement செய்ய மறக்கவில்லை என்பதை இது உறுதி செய்கிறது.
Ready to learn this topic?
Components-ஐ external systems-உடன் synchronize செய்வது எப்படி என்பதை அறிய Synchronizing with Effects-ஐ படியுங்கள்.
Read Moreஉங்களுக்கு Effect தேவைப்படாமல் இருக்கலாம்
Effects என்பது React paradigm-இலிருந்து ஒரு escape hatch. அவை React-க்கு “வெளியே செல்ல” மற்றும் உங்கள் components-ஐ ஏதாவது external system-உடன் synchronize செய்ய அனுமதிக்கின்றன. External system எதுவும் இல்லையெனில் (உதாரணமாக, சில props அல்லது state மாறும்போது component state update செய்ய விரும்பினால்), Effect தேவையில்லை. தேவையற்ற Effects-ஐ remove செய்வது உங்கள் code-ஐ follow செய்ய திறமையாகவும், வேகமாக run ஆகவும், குறைவான error-prone ஆகவும் மாற்றும்.
Effects தேவையில்லாத இரண்டு பொதுவான cases:
- Rendering-க்காக data transform செய்ய Effects தேவையில்லை.
- User events handle செய்ய Effects தேவையில்லை.
உதாரணமாக, மற்ற state அடிப்படையில் சில state adjust செய்ய Effect தேவையில்லை:
function Form() {
const [firstName, setFirstName] = useState('Taylor');
const [lastName, setLastName] = useState('Swift');
// 🔴 Avoid: redundant state and unnecessary Effect
const [fullName, setFullName] = useState('');
useEffect(() => {
setFullName(firstName + ' ' + lastName);
}, [firstName, lastName]);
// ...
}அதற்கு பதிலாக, rendering போது முடிந்த அளவு calculate செய்யுங்கள்:
function Form() {
const [firstName, setFirstName] = useState('Taylor');
const [lastName, setLastName] = useState('Swift');
// ✅ Good: calculated during rendering
const fullName = firstName + ' ' + lastName;
// ...
}ஆனால், external systems-உடன் synchronize செய்ய Effects தேவைப்படும்.
Ready to learn this topic?
தேவையற்ற Effects-ஐ remove செய்வது எப்படி என்பதை அறிய You Might Not Need an Effect-ஐ படியுங்கள்.
Read MoreReactive effects-ன் lifecycle
Effects-க்கு components-இலிருந்து வேறுபட்ட lifecycle உள்ளது. Components mount, update, அல்லது unmount ஆகலாம். Effect இரண்டு விஷயங்கள் மட்டுமே செய்ய முடியும்: ஏதாவது ஒன்றை synchronize செய்ய தொடங்குவது, பின்னர் அதை synchronize செய்வதை நிறுத்துவது. உங்கள் Effect காலத்துடன் மாறும் props மற்றும் state-ஐ சார்ந்திருந்தால், இந்த cycle பலமுறை நடக்கலாம்.
இந்த Effect roomId prop-ன் value-ஐ சார்ந்துள்ளது. Props reactive values; அதாவது அவை re-render போது மாறக்கூடும். roomId மாறினால் Effect எப்படி re-synchronizes செய்கிறது (server-க்கு மீண்டும் connect செய்கிறது) என்பதை கவனியுங்கள்:
import { useState, useEffect } from 'react'; import { createConnection } from './chat.js'; const serverUrl = 'https://localhost:1234'; function ChatRoom({ roomId }) { useEffect(() => { const connection = createConnection(serverUrl, roomId); connection.connect(); return () => connection.disconnect(); }, [roomId]); return <h1>{roomId} room-க்கு வரவேற்கிறோம்!</h1>; } export default function App() { const [roomId, setRoomId] = useState('general'); return ( <> <label> Chat room-ஐ தேர்வு செய்க:{' '} <select value={roomId} onChange={e => setRoomId(e.target.value)} > <option value="general">general</option> <option value="travel">travel</option> <option value="music">music</option> </select> </label> <hr /> <ChatRoom roomId={roomId} /> </> ); }
உங்கள் Effect-ன் dependencies-ஐ சரியாக specify செய்துள்ளீர்களா என்பதை check செய்ய React linter rule ஒன்றை வழங்குகிறது. மேலுள்ள example-இல் dependencies list-இல் roomId specify செய்ய மறந்தால், linter அந்த bug-ஐ தானாக கண்டறியும்.
Ready to learn this topic?
Effect-ன் lifecycle component-ன் lifecycle-இலிருந்து எப்படி வேறுபடுகிறது என்பதை அறிய Lifecycle of Reactive Events-ஐ படியுங்கள்.
Read MoreEvents-ஐ Effects-இலிருந்து பிரித்தல்
Event handlers அதே interaction-ஐ மீண்டும் செய்தால் மட்டுமே re-run ஆகும். Event handlers-க்கு மாறாக, Effects அவை read செய்யும் props அல்லது state போன்ற values கடைசி render-இலிருந்து வேறுபட்டால் re-synchronize ஆகும். சில நேரங்களில், இருவகை behaviors-ன் mix ஒன்றை விரும்பலாம்: சில values-க்கு பதிலாக re-run ஆகும் Effect, மற்ற values-க்கு அல்ல.
Effects-க்குள் உள்ள அனைத்து code-மும் reactive. அது read செய்யும் reactive value re-render காரணமாக மாறினால் மீண்டும் run ஆகும். உதாரணமாக, roomId அல்லது theme மாறினால் இந்த Effect chat-க்கு மீண்டும் connect செய்யும்:
import { useState, useEffect } from 'react'; import { createConnection, sendMessage } from './chat.js'; import { showNotification } from './notifications.js'; const serverUrl = 'https://localhost:1234'; function ChatRoom({ roomId, theme }) { useEffect(() => { const connection = createConnection(serverUrl, roomId); connection.on('connected', () => { showNotification('இணைக்கப்பட்டது!', theme); }); connection.connect(); return () => connection.disconnect(); }, [roomId, theme]); return <h1>{roomId} room-க்கு வரவேற்கிறோம்!</h1> } export default function App() { const [roomId, setRoomId] = useState('general'); const [isDark, setIsDark] = useState(false); return ( <> <label> Chat room-ஐ தேர்வு செய்க:{' '} <select value={roomId} onChange={e => setRoomId(e.target.value)} > <option value="general">general</option> <option value="travel">travel</option> <option value="music">music</option> </select> </label> <label> <input type="checkbox" checked={isDark} onChange={e => setIsDark(e.target.checked)} /> Dark theme பயன்படுத்து </label> <hr /> <ChatRoom roomId={roomId} theme={isDark ? 'dark' : 'light'} /> </> ); }
இது ideal அல்ல. roomId மாறினால் மட்டுமே chat மீண்டும் connect ஆக வேண்டும். theme switch செய்ததால் chat மீண்டும் connect ஆகக் கூடாது! theme read செய்யும் code-ஐ உங்கள் Effect-இலிருந்து Effect Event ஒன்றுக்குள் நகர்த்துங்கள்:
import { useState, useEffect } from 'react'; import { useEffectEvent } from 'react'; import { createConnection, sendMessage } from './chat.js'; import { showNotification } from './notifications.js'; const serverUrl = 'https://localhost:1234'; function ChatRoom({ roomId, theme }) { const onConnected = useEffectEvent(() => { showNotification('இணைக்கப்பட்டது!', theme); }); useEffect(() => { const connection = createConnection(serverUrl, roomId); connection.on('connected', () => { onConnected(); }); connection.connect(); return () => connection.disconnect(); }, [roomId]); return <h1>{roomId} room-க்கு வரவேற்கிறோம்!</h1> } export default function App() { const [roomId, setRoomId] = useState('general'); const [isDark, setIsDark] = useState(false); return ( <> <label> Chat room-ஐ தேர்வு செய்க:{' '} <select value={roomId} onChange={e => setRoomId(e.target.value)} > <option value="general">general</option> <option value="travel">travel</option> <option value="music">music</option> </select> </label> <label> <input type="checkbox" checked={isDark} onChange={e => setIsDark(e.target.checked)} /> Dark theme பயன்படுத்து </label> <hr /> <ChatRoom roomId={roomId} theme={isDark ? 'dark' : 'light'} /> </> ); }
Effect Events-க்குள் உள்ள code reactive அல்ல, எனவே theme மாறுவது இனி உங்கள் Effect-ஐ மீண்டும் connect செய்யாது.
Ready to learn this topic?
சில values Effects-ஐ மீண்டும் trigger செய்வதைத் தடுப்பது எப்படி என்பதை அறிய Separating Events from Effects-ஐ படியுங்கள்.
Read MoreEffect dependencies remove செய்தல்
நீங்கள் Effect எழுதும்போது, அந்த Effect read செய்யும் ஒவ்வொரு reactive value-யும் (props மற்றும் state போன்றவை) உங்கள் Effect-ன் dependencies list-இல் சேர்க்கப்பட்டுள்ளதா என்பதை linter verify செய்யும். இது உங்கள் Effect உங்கள் component-ன் latest props மற்றும் state-உடன் synchronized ஆக இருப்பதை உறுதி செய்கிறது. தேவையற்ற dependencies உங்கள் Effect மிக அடிக்கடி run ஆகவோ, அல்லது infinite loop உருவாக்கவோ செய்யலாம். அவற்றை எப்படி remove செய்வது என்பது case-ஐப் பொறுத்தது.
உதாரணமாக, இந்த Effect input edit செய்யும் ஒவ்வொரு முறையும் மீண்டும் உருவாக்கப்படும் options object-ஐ சார்ந்துள்ளது:
import { useState, useEffect } from 'react'; import { createConnection } from './chat.js'; const serverUrl = 'https://localhost:1234'; function ChatRoom({ roomId }) { const [message, setMessage] = useState(''); const options = { serverUrl: serverUrl, roomId: roomId }; useEffect(() => { const connection = createConnection(options); connection.connect(); return () => connection.disconnect(); }, [options]); return ( <> <h1>{roomId} room-க்கு வரவேற்கிறோம்!</h1> <input value={message} onChange={e => setMessage(e.target.value)} /> </> ); } export default function App() { const [roomId, setRoomId] = useState('general'); return ( <> <label> Chat room-ஐ தேர்வு செய்க:{' '} <select value={roomId} onChange={e => setRoomId(e.target.value)} > <option value="general">general</option> <option value="travel">travel</option> <option value="music">music</option> </select> </label> <hr /> <ChatRoom roomId={roomId} /> </> ); }
அந்த chat-இல் message type செய்யத் தொடங்கும் ஒவ்வொரு முறையும் chat மீண்டும் connect ஆக வேண்டாம். இந்த problem-ஐ fix செய்ய, options object உருவாக்கத்தை Effect-க்குள் நகர்த்துங்கள்; அப்போது Effect roomId string-ஐ மட்டும் சாரும்:
import { useState, useEffect } from 'react'; import { createConnection } from './chat.js'; const serverUrl = 'https://localhost:1234'; function ChatRoom({ roomId }) { const [message, setMessage] = useState(''); useEffect(() => { const options = { serverUrl: serverUrl, roomId: roomId }; const connection = createConnection(options); connection.connect(); return () => connection.disconnect(); }, [roomId]); return ( <> <h1>{roomId} room-க்கு வரவேற்கிறோம்!</h1> <input value={message} onChange={e => setMessage(e.target.value)} /> </> ); } export default function App() { const [roomId, setRoomId] = useState('general'); return ( <> <label> Chat room-ஐ தேர்வு செய்க:{' '} <select value={roomId} onChange={e => setRoomId(e.target.value)} > <option value="general">general</option> <option value="travel">travel</option> <option value="music">music</option> </select> </label> <hr /> <ChatRoom roomId={roomId} /> </> ); }
options dependency-ஐ remove செய்ய dependency list-ஐ edit செய்வதிலிருந்து நீங்கள் தொடங்கவில்லை என்பதை கவனியுங்கள். அது தவறாக இருக்கும். அதற்கு பதிலாக, surrounding code-ஐ மாற்றி dependency தேவையற்றதாக ஆக்கியீர்கள். Dependency list-ஐ உங்கள் Effect code பயன்படுத்தும் அனைத்து reactive values-ன் list ஆக நினைத்துக்கொள்ளுங்கள். அந்த list-இல் என்ன வைக்க வேண்டும் என்று நீங்கள் intentional ஆக தேர்வு செய்வதில்லை. List உங்கள் code-ஐ describe செய்கிறது. Dependency list-ஐ மாற்ற, code-ஐ மாற்றுங்கள்.
Ready to learn this topic?
உங்கள் Effect குறைவாக re-run ஆக செய்வது எப்படி என்பதை அறிய Removing Effect Dependencies-ஐ படியுங்கள்.
Read MoreCustom Hooks மூலம் logic reuse செய்தல்
React useState, useContext, மற்றும் useEffect போன்ற built-in Hooks உடன் வருகிறது. சில நேரங்களில், data fetch செய்ய, user online-இல் உள்ளாரா என்பதை track செய்ய, அல்லது chat room-க்கு connect செய்ய போன்ற குறிப்பிட்ட நோக்கத்திற்கான Hook ஒன்று இருந்தால் நன்றாக இருக்கும் என்று நினைப்பீர்கள். இதற்காக, உங்கள் application’s needs-க்காக உங்கள் சொந்த Hooks உருவாக்கலாம்.
இந்த example-இல், usePointerPosition custom Hook cursor position-ஐ track செய்கிறது; useDelayedValue custom Hook நீங்கள் pass செய்த value-ஐவிட குறிப்பிட்ட milliseconds அளவிற்கு “lagging behind” இருக்கும் value-ஐ return செய்கிறது. Cursor-ஐ sandbox preview area மீது நகர்த்தி, cursor-ஐ பின்தொடரும் moving trail of dots-ஐப் பாருங்கள்:
import { usePointerPosition } from './usePointerPosition.js'; import { useDelayedValue } from './useDelayedValue.js'; export default function Canvas() { const pos1 = usePointerPosition(); const pos2 = useDelayedValue(pos1, 100); const pos3 = useDelayedValue(pos2, 200); const pos4 = useDelayedValue(pos3, 100); const pos5 = useDelayedValue(pos4, 50); return ( <> <Dot position={pos1} opacity={1} /> <Dot position={pos2} opacity={0.8} /> <Dot position={pos3} opacity={0.6} /> <Dot position={pos4} opacity={0.4} /> <Dot position={pos5} opacity={0.2} /> </> ); } function Dot({ position, opacity }) { return ( <div style={{ position: 'absolute', backgroundColor: 'pink', borderRadius: '50%', opacity, transform: `translate(${position.x}px, ${position.y}px)`, pointerEvents: 'none', left: -20, top: -20, width: 40, height: 40, }} /> ); }
நீங்கள் custom Hooks உருவாக்கலாம், அவற்றை ஒன்றாக compose செய்யலாம், அவற்றுக்கு இடையில் data pass செய்யலாம், மேலும் components இடையே அவற்றை reuse செய்யலாம். உங்கள் app வளரும்போது, நீங்கள் ஏற்கனவே எழுதிய custom Hooks-ஐ reuse செய்ய முடிவதால், கைமுறையாக குறைவான Effects எழுதுவீர்கள். React community maintain செய்யும் பல சிறந்த custom Hooks-உம் உள்ளன.
Ready to learn this topic?
Components இடையே logic பகிர்வது எப்படி என்பதை அறிய Reusing Logic with Custom Hooks-ஐ படியுங்கள்.
Read Moreஅடுத்து என்ன?
இந்த chapter-ஐ page by page படிக்கத் தொடங்க Referencing Values with Refs-க்கு செல்லுங்கள்!