Events-க்கு பதிலளித்தல்
உங்கள் JSX-க்கு event handlers சேர்க்க React அனுமதிக்கிறது. Event handlers என்பது clicking, hovering, form inputs-ஐ focusing செய்வது போன்ற interactions-க்கு பதிலாக trigger ஆகும் உங்கள் சொந்த functions.
நீங்கள் கற்றுக்கொள்ள போவது
- Event handler எழுதும் வெவ்வேறு வழிகள்
- Parent component-இலிருந்து event handling logic-ஐ எப்படி pass செய்வது
- Events எப்படி propagate ஆகின்றன மற்றும் அவற்றை எப்படி stop செய்வது
Event handlers சேர்த்தல்
Event handler சேர்க்க, முதலில் ஒரு function-ஐ define செய்து, பின்னர் அதை பொருத்தமான JSX tag-க்கு prop ஆக pass செய்வீர்கள். உதாரணமாக, இன்னும் எதையும் செய்யாத button ஒன்று இங்கே:
export default function Button() { return ( <button> நான் எதையும் செய்யவில்லை </button> ); }
User click செய்தால் ஒரு message காட்ட, இந்த மூன்று படிகளைப் பின்பற்றலாம்:
- உங்கள்
Buttoncomponent-க்குள்handleClickஎனும் function-ஐ declare செய்யுங்கள். - அந்த function-க்குள் logic-ஐ implement செய்யுங்கள் (message காட்ட
alertபயன்படுத்துங்கள்). <button>JSX-க்குonClick={handleClick}சேர்க்குங்கள்.
export default function Button() { function handleClick() { alert('நீங்கள் என்னை click செய்தீர்கள்!'); } return ( <button onClick={handleClick}> என்னை click செய்க </button> ); }
நீங்கள் handleClick function-ஐ define செய்து, பின்னர் அதை <button>-க்கு prop ஆக pass செய்தீர்கள். handleClick ஒரு event handler. Event handler functions:
- பொதுவாக உங்கள் components-க்குள் define செய்யப்படும்.
handleஎன்று தொடங்கி, அதன் பின் event பெயர் வரும் names கொண்டிருக்கும்.
Convention படி, event handlers-க்கு handle தொடர்ந்து event name வரும் பெயர் வைப்பது பொதுவானது. onClick={handleClick}, onMouseEnter={handleMouseEnter} போன்றவற்றை அடிக்கடி காண்பீர்கள்.
மாற்றாக, JSX-க்குள் inline ஆக event handler define செய்யலாம்:
<button onClick={function handleClick() {
alert('நீங்கள் என்னை click செய்தீர்கள்!');
}}>அல்லது, இன்னும் சுருக்கமாக arrow function பயன்படுத்தலாம்:
<button onClick={() => {
alert('நீங்கள் என்னை click செய்தீர்கள்!');
}}>இந்த styles அனைத்தும் equivalent. Short functions-க்கு inline event handlers வசதியானவை.
Event handlers-இல் props-ஐ வாசித்தல்
Event handlers ஒரு component-க்குள் declared செய்யப்படுவதால், அவற்றுக்கு அந்த component-ன் props access இருக்கும். Click செய்தால் தனது message prop உடன் alert காட்டும் button இதோ:
function AlertButton({ message, children }) { return ( <button onClick={() => alert(message)}> {children} </button> ); } export default function Toolbar() { return ( <div> <AlertButton message="இயக்கப்படுகிறது!"> Movie-ஐ இயக்கு </AlertButton> <AlertButton message="Upload செய்யப்படுகிறது!"> Image-ஐ upload செய் </AlertButton> </div> ); }
இதனால் இந்த இரண்டு buttons வெவ்வேறு messages காட்ட முடியும். அவற்றுக்கு pass செய்யப்பட்ட messages-ஐ மாற்றிப் பாருங்கள்.
Event handlers-ஐ props ஆக pass செய்தல்
Parent component ஒரு child-ன் event handler-ஐ specify செய்ய வேண்டும் என்பது அடிக்கடி வரும். Buttons-ஐ எடுத்துக்கொள்ளுங்கள்: Button component-ஐ எங்கு பயன்படுத்துகிறீர்கள் என்பதைப் பொறுத்து வேறு function execute செய்ய விரும்பலாம்—ஒன்று movie play செய்யலாம், மற்றொன்று image upload செய்யலாம்.
இதைக் செய்ய, component தனது parent-இலிருந்து பெறும் prop-ஐ event handler ஆக இதுபோல் pass செய்யுங்கள்:
function Button({ onClick, children }) { return ( <button onClick={onClick}> {children} </button> ); } function PlayButton({ movieName }) { function handlePlayClick() { alert(`${movieName} இயக்கப்படுகிறது!`); } return ( <Button onClick={handlePlayClick}> "{movieName}"-ஐ இயக்கு </Button> ); } function UploadButton() { return ( <Button onClick={() => alert('Upload செய்யப்படுகிறது!')}> Image-ஐ upload செய் </Button> ); } export default function Toolbar() { return ( <div> <PlayButton movieName="Kiki's Delivery Service" /> <UploadButton /> </div> ); }
இங்கே, Toolbar component ஒரு PlayButton மற்றும் ஒரு UploadButton-ஐ render செய்கிறது:
PlayButtonஉள்ளே உள்ளButton-க்குhandlePlayClick-ஐonClickprop ஆக pass செய்கிறது.UploadButtonஉள்ளே உள்ளButton-க்கு() => alert('Upload செய்யப்படுகிறது!')-ஐonClickprop ஆக pass செய்கிறது.
இறுதியாக, உங்கள் Button component onClick எனும் prop-ஐ ஏற்கிறது. அது அந்த prop-ஐ built-in browser <button>-க்கு onClick={onClick} உடன் நேரடியாக pass செய்கிறது. இதனால் click போது pass செய்யப்பட்ட function-ஐ call செய்ய React-க்கு தெரியும்.
நீங்கள் design system பயன்படுத்தினால், buttons போன்ற components styling-ஐ கொண்டிருப்பதும் behavior-ஐ specify செய்யாததும் பொதுவானது. அதற்கு பதிலாக, PlayButton மற்றும் UploadButton போன்ற components event handlers-ஐ கீழே pass செய்யும்.
Event handler props-க்கு பெயர் வைப்பது
<button> மற்றும் <div> போன்ற built-in components, onClick போன்ற browser event names-ஐ மட்டுமே support செய்கின்றன. ஆனால் நீங்கள் உங்கள் சொந்த components கட்டும்போது, அவற்றின் event handler props-க்கு உங்களுக்கு விருப்பமான எந்தப் பெயரையும் வைக்கலாம்.
Convention படி, event handler props on என்று தொடங்கி, அதன் பின் capital letter வர வேண்டும்.
உதாரணமாக, Button component-ன் onClick prop-க்கு onSmash என்று பெயர் வைத்திருக்கலாம்:
function Button({ onSmash, children }) { return ( <button onClick={onSmash}> {children} </button> ); } export default function App() { return ( <div> <Button onSmash={() => alert('இயக்கப்படுகிறது!')}> Movie-ஐ இயக்கு </Button> <Button onSmash={() => alert('Upload செய்யப்படுகிறது!')}> Image-ஐ upload செய் </Button> </div> ); }
இந்த example-இல், browser <button> (lowercase) இன்னும் onClick எனும் prop-ஐத் தேவைப்படுகின்றது என்பதை <button onClick={onSmash}> காட்டுகிறது. ஆனால் உங்கள் custom Button component பெறும் prop name உங்கள் விருப்பம்!
உங்கள் component பல interactions-ஐ support செய்தால், app-specific concepts-ஐ வைத்து event handler props-க்கு பெயர் வைக்கலாம். உதாரணமாக, இந்த Toolbar component onPlayMovie மற்றும் onUploadImage event handlers-ஐப் பெறுகிறது:
export default function App() { return ( <Toolbar onPlayMovie={() => alert('இயக்கப்படுகிறது!')} onUploadImage={() => alert('Upload செய்யப்படுகிறது!')} /> ); } function Toolbar({ onPlayMovie, onUploadImage }) { return ( <div> <Button onClick={onPlayMovie}> Movie-ஐ இயக்கு </Button> <Button onClick={onUploadImage}> Image-ஐ upload செய் </Button> </div> ); } function Button({ onClick, children }) { return ( <button onClick={onClick}> {children} </button> ); }
App component, Toolbar onPlayMovie அல்லது onUploadImage கொண்டு என்ன செய்யும் என்பதை அறிய தேவையில்லை என்பதை கவனியுங்கள். அது Toolbar-ன் implementation detail. இங்கே, Toolbar அவற்றை தனது Buttons-க்கு onClick handlers ஆக கீழே pass செய்கிறது; ஆனால் பின்னர் keyboard shortcut-இலும் அவற்றை trigger செய்யலாம். onPlayMovie போன்ற app-specific interactions பெயர்களை props-க்கு வைப்பது, அவை பின்னர் எப்படி பயன்படுத்தப்படுகின்றன என்பதை மாற்றும் flexibility-யை உங்களுக்கு வழங்குகிறது.
Event propagation
Event handlers, உங்கள் component-க்கு இருக்கக்கூடிய எந்த children-இலிருந்தும் events-ஐ catch செய்யும். ஒரு event tree-யில் மேலே “bubbles” அல்லது “propagates” ஆகிறது என்று சொல்வோம்: event நடந்த இடத்திலிருந்து தொடங்கி tree-யில் மேலே செல்கிறது.
இந்த <div> இரண்டு buttons-ஐ கொண்டுள்ளது. <div> மற்றும் ஒவ்வொரு button-க்கும் தனி onClick handlers உள்ளன. Button ஒன்றை click செய்தால் எந்த handlers fire ஆகும் என்று நினைக்கிறீர்கள்?
export default function Toolbar() { return ( <div className="Toolbar" onClick={() => { alert('நீங்கள் toolbar-ஐ click செய்தீர்கள்!'); }}> <button onClick={() => alert('இயக்கப்படுகிறது!')}> Movie-ஐ இயக்கு </button> <button onClick={() => alert('Upload செய்யப்படுகிறது!')}> Image-ஐ upload செய் </button> </div> ); }
ஏதாவது button-ஐ click செய்தால், முதலில் அதன் onClick run ஆகும்; அதன் பின் parent <div>-ன் onClick run ஆகும். எனவே இரண்டு messages தோன்றும். Toolbar-ஐத் தானே click செய்தால், parent <div>-ன் onClick மட்டும் run ஆகும்.
Propagation-ஐ நிறுத்துதல்
Event handlers தங்கள் ஒரே argument ஆக event object-ஐப் பெறுகின்றன. Convention படி, அது பொதுவாக e என்று அழைக்கப்படுகிறது; அது “event” என்பதைக் குறிக்கும். Event பற்றிய தகவலை வாசிக்க இந்த object-ஐ பயன்படுத்தலாம்.
அந்த event object propagation-ஐ stop செய்யவும் அனுமதிக்கிறது. Event parent components-ஐ அடையாமல் தடுக்க விரும்பினால், இந்த Button component செய்வது போல e.stopPropagation() call செய்ய வேண்டும்:
function Button({ onClick, children }) { return ( <button onClick={e => { e.stopPropagation(); onClick(); }}> {children} </button> ); } export default function Toolbar() { return ( <div className="Toolbar" onClick={() => { alert('நீங்கள் toolbar-ஐ click செய்தீர்கள்!'); }}> <Button onClick={() => alert('இயக்கப்படுகிறது!')}> Movie-ஐ இயக்கு </Button> <Button onClick={() => alert('Upload செய்யப்படுகிறது!')}> Image-ஐ upload செய் </Button> </div> ); }
Button ஒன்றை click செய்தால்:
<button>-க்கு pass செய்யப்பட்டonClickhandler-ஐ React call செய்கிறது.Button-இல் defined செய்யப்பட்ட அந்த handler, பின்வருவன செய்கிறது:e.stopPropagation()-ஐ call செய்து, event மேலும் bubble ஆகாமல் தடுக்கிறது.Toolbarcomponent-இலிருந்து prop ஆக pass செய்யப்பட்டonClickfunction-ஐ call செய்கிறது.
Toolbarcomponent-இல் defined செய்யப்பட்ட அந்த function, button-ன் சொந்த alert-ஐ display செய்கிறது.- Propagation stop செய்யப்பட்டதால், parent
<div>-ன்onClickhandler run ஆகாது.
e.stopPropagation()-ன் விளைவாக, buttons-ஐ click செய்தால் இப்போது இரண்டு alerts-க்கு பதிலாக (<button> மற்றும் parent toolbar <div>-இலிருந்து), ஒரு alert மட்டும் (<button>-இலிருந்து) காட்டும். Button click செய்வது surrounding toolbar click செய்வதற்கு சமமல்ல; எனவே இந்த UI-க்கு propagation-ஐ stop செய்வது பொருத்தமானது.
Deep Dive
அரிதான cases-இல், child elements-இல் உள்ள அனைத்து events-ஐயும், அவை propagation stop செய்திருந்தாலும் catch செய்ய வேண்டியிருக்கும். உதாரணமாக, propagation logic எப்படியிருந்தாலும் ஒவ்வொரு click-ஐயும் analytics-க்கு log செய்ய விரும்பலாம். Event name-ன் முடிவில் Capture சேர்ப்பதன் மூலம் இதைச் செய்யலாம்:
<div onClickCapture={() => { /* இது முதலில் run ஆகும் */ }}>
<button onClick={e => e.stopPropagation()} />
<button onClick={e => e.stopPropagation()} />
</div>ஒவ்வொரு event-மும் மூன்று phases-இல் propagate ஆகிறது:
- அது கீழே பயணித்து, அனைத்து
onClickCapturehandlers-ஐ call செய்கிறது. - Click செய்யப்பட்ட element-ன்
onClickhandler-ஐ run செய்கிறது. - அது மேலே பயணித்து, அனைத்து
onClickhandlers-ஐ call செய்கிறது.
Capture events routers அல்லது analytics போன்ற code-க்கு பயனுள்ளவை; ஆனால் app code-இல் அவற்றை நீங்கள் பெரும்பாலும் பயன்படுத்தமாட்டீர்கள்.
Propagation-க்கு மாற்றாக handlers-ஐ pass செய்தல்
இந்த click handler ஒரு வரி code-ஐ run செய்து பிறகு parent pass செய்த onClick prop-ஐ call செய்வதை கவனியுங்கள்:
function Button({ onClick, children }) {
return (
<button onClick={e => {
e.stopPropagation();
onClick();
}}>
{children}
</button>
);
}Parent onClick event handler-ஐ call செய்வதற்கு முன் இந்த handler-க்கு இன்னும் code சேர்க்கலாம். இந்த pattern propagation-க்கு ஒரு alternative வழங்குகிறது. இது child component event-ஐ handle செய்ய அனுமதிக்கிறது; அதே சமயம் parent component கூடுதல் behavior ஒன்றை specify செய்யவும் அனுமதிக்கிறது. Propagation போல இது automatic அல்ல. ஆனால் இந்த pattern-ன் நன்மை, event ஒன்றின் விளைவாக execute ஆகும் code chain முழுவதையும் தெளிவாகப் பின்தொடர முடியும் என்பதுதான்.
நீங்கள் propagation-ஐ சார்ந்து, எந்த handlers ஏன் execute ஆகின்றன என்பதை trace செய்வது கடினமாக இருந்தால், இந்த அணுகுமுறையை முயற்சி செய்யுங்கள்.
Default behavior-ஐத் தடுப்பது
சில browser events-க்கு அவற்றுடன் தொடர்புடைய default behavior உள்ளது. உதாரணமாக, ஒரு <form> submit event, அதற்குள் உள்ள button click செய்யப்பட்டால் நடக்கும்; default ஆக அது முழு page-ஐ reload செய்யும்:
export default function Signup() { return ( <form onSubmit={() => alert('Submit செய்யப்படுகிறது!')}> <input /> <button>அனுப்பு</button> </form> ); }
இது நடக்காமல் தடுக்க event object-இல் e.preventDefault() call செய்யலாம்:
export default function Signup() { return ( <form onSubmit={e => { e.preventDefault(); alert('Submit செய்யப்படுகிறது!'); }}> <input /> <button>அனுப்பு</button> </form> ); }
e.stopPropagation() மற்றும் e.preventDefault()-ஐ குழப்ப வேண்டாம். இரண்டும் பயனுள்ளவை, ஆனால் தொடர்பில்லாதவை:
e.stopPropagation()மேலுள்ள tags-க்கு attach செய்யப்பட்ட event handlers fire ஆகாமல் தடுக்கிறது.e.preventDefault()default browser behavior உள்ள சில events-க்கு அந்த behavior-ஐத் தடுக்கிறது.
Event handlers-க்கு side effects இருக்க முடியுமா?
மிகவும் முடியும்! Side effects-க்கு event handlers சிறந்த இடம்.
Rendering functions போல அல்லாமல், event handlers pure ஆக இருக்க வேண்டியதில்லை; எனவே ஏதாவது ஒன்றை மாற்ற அது சிறந்த இடம்—உதாரணமாக, typing-க்கு பதிலாக input-ன் value-ஐ மாற்றுதல், அல்லது button press-க்கு பதிலாக list-ஐ மாற்றுதல். ஆனால் எந்த தகவலையும் மாற்ற, முதலில் அதை store செய்ய ஒரு வழி தேவை. React-இல், இது state, component-ன் memory பயன்படுத்தி செய்யப்படுகிறது. அடுத்த page-இல் இதைப் பற்றி அனைத்தையும் கற்றுக்கொள்வீர்கள்.
Recap
<button>போன்ற element-க்கு function-ஐ prop ஆக pass செய்வதன் மூலம் events-ஐ handle செய்யலாம்.- Event handlers pass செய்யப்பட வேண்டும், call செய்யப்படக்கூடாது!
onClick={handleClick},onClick={handleClick()}அல்ல. - Event handler function-ஐ தனியாகவோ inline ஆகவோ define செய்யலாம்.
- Event handlers component-க்குள் define செய்யப்படுகின்றன, எனவே அவை props-ஐ access செய்ய முடியும்.
- Parent-இல் event handler ஒன்றை declare செய்து child-க்கு prop ஆக pass செய்யலாம்.
- Application-specific names கொண்டு உங்கள் சொந்த event handler props-ஐ define செய்யலாம்.
- Events மேலே propagate ஆகும். அதைத் தடுக்க முதல் argument-இல்
e.stopPropagation()call செய்யுங்கள். - Events-க்கு வேண்டாத default browser behavior இருக்கலாம். அதைத் தடுக்க
e.preventDefault()call செய்யுங்கள். - Child handler-இலிருந்து event handler prop-ஐ explicit ஆக call செய்வது propagation-க்கு நல்ல alternative.
Challenge 1 of 2: Event handler-ஐ சரிசெய்யுங்கள்
இந்த button-ஐ click செய்தால் page background white மற்றும் black இடையே மாற வேண்டும். ஆனால் அதை click செய்தால் எதுவும் நடக்கவில்லை. பிரச்சினையைச் சரிசெய்யுங்கள். (handleClick-க்குள் உள்ள logic பற்றி கவலைப்பட வேண்டாம்—அந்த பகுதி சரியாக இருக்கிறது.)
export default function LightSwitch() { function handleClick() { let bodyStyle = document.body.style; if (bodyStyle.backgroundColor === 'black') { bodyStyle.backgroundColor = 'white'; } else { bodyStyle.backgroundColor = 'black'; } } return ( <button onClick={handleClick()}> விளக்குகளை மாற்று </button> ); }