0% found this document useful (0 votes)
14 views

3 04 Forms

The document discusses forms and events in React JSX. It explains that React exposes a more uniform interface for forms compared to native HTML forms. It describes how to handle values, change events, and the state of controlled form components in React. Form elements are stateful, so React components need to manage the state and update on changes to correctly render the virtual DOM.

Uploaded by

FX
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
14 views

3 04 Forms

The document discusses forms and events in React JSX. It explains that React exposes a more uniform interface for forms compared to native HTML forms. It describes how to handle values, change events, and the state of controlled form components in React. Form elements are stateful, so React components need to manage the state and update on changes to correctly render the virtual DOM.

Uploaded by

FX
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 25

Forms

The Foundations of User Interaction


Fulvio Corno
Luigi De Russis
Enrico Masala

Applicazioni Web I - Web Applications I - 2022/2023


https://react.dev/reference/react-
dom/components#form-components

Full Stack React, Chapter “Forms”

React Handbook, Chapter “JSX”

Forms, Events and Event Handlers

FORMS IN JSX

2
Applicazioni Web I - Web Applications I - 2022/2023
HTML Forms
• (Native) HTML Forms are inconsistent: different ways of handling values,
events etc. depending on the type of input element
– Consequence of backward compatibility
• For instance:
– onChange on a radio button is not easy to handle
– value in a textarea does not work, etc.
• React flattens this behavior exposing (via JSX) a more uniform interface
– Synthetic Events

3
Applicazioni Web I - Web Applications I - 2022/2023
Value in JSX forms
• The value attribute always holds the current value of the field
• The defaultValue attribute holds the default value that was set when
the field was created
• This also applies to
– textarea: the content is in the value attribute; it is NOT to be taken from the
actual content of the <textarea>…</textarea> tag
– select: do not use the <option selected> syntax, but <select
value='id'>

4
Applicazioni Web I - Web Applications I - 2022/2023
Change Events in JSX Forms
• React provides a more consistent onChange event
• By passing a function to the onChange attribute you can subscribe to
events on form fields (every time value changes)
• onChange fires when typing a single character into an input or
textarea field
• It works consistently across fields: even radio, select and checkbox
input fields fire a onChange event

5
Applicazioni Web I - Web Applications I - 2022/2023
Event Handlers
• An Event Handler callback function is called with one parameter: an
event object
• All event objects have a standard set of properties
– event.target: source of the event
• Some events, depending on categories, have more specific properties

6
Applicazioni Web I - Web Applications I - 2022/2023
Synthetic Events https://react.dev/reference/react-
dom/components/common#react-event-object

• “High level events” wrap the boolean bubbles


boolean cancelable
corresponding DOM Events DOMEventTarget currentTarget
• Same attributes as DOMEvent boolean defaultPrevented
number eventPhase
• target points to the source of boolean isTrusted
the event. DOMEvent nativeEvent
void preventDefault()
• In case of a form element boolean isDefaultPrevented()
void stopPropagation()
– target.value = current input boolean isPropagationStopped()
value DOMEventTarget target
– target.name = input element number timeStamp
string type
name
7
Applicazioni Web I - Web Applications I - 2022/2023
Synthetic Events https://reactjs.org/docs/events.html

Category Events
Clipboard onCopy onCut onPaste
Composition onCompositionEnd onCompositionStart onCompositionUpdate
Keyboard onKeyDown onKeyPress onKeyUp
Focus onFocus onBlur
Form onChange onInput onInvalid onReset onSubmit
Generic onError onLoad
Mouse onClick onContextMenu onDoubleClick onDrag onDragEnd onDragEnter onDragExit onDragLeave onDragOver onDragStart onDrop
onMouseDown onMouseEnter onMouseLeave onMouseMove onMouseOut onMouseOver onMouseUp
Pointer onPointerDown onPointerMove onPointerUp onPointerCancel onGotPointerCapture onLostPointerCapture onPointerEnter
onPointerLeave onPointerOver onPointerOut
Selection onSelect
Touch onTouchCancel onTouchEnd onTouchMove onTouchStart
UI onScroll
Wheel onWheel
Media onAbort onCanPlay onCanPlayThrough onDurationChange onEmptied onEncrypted onEnded onError onLoadedData
onLoadedMetadata onLoadStart onPause onPlay onPlaying onProgress onRateChange onSeeked onSeeking onStalled onSuspend
onTimeUpdate onVolumeChange onWaiting
Image onLoad onError
Animation onAnimationStart onAnimationEnd onAnimationIteration
8
Transition onTransitionEnd
Applicazioni Web I - Web Applications I - 2022/2023
Tip: Defining Event Handlers
• Define the function as… const handler = () => { ... }
– an arrow function
– a function expression
handler = function() { ... }

9
Applicazioni Web I - Web Applications I - 2022/2023
Tip: Defining Event Handlers
• Pass the name of the function as return <div handler={handler} />
a prop
– As a function object (not string)
return <div handler={handler()} />
– Don’t call the function
return <div handler='handler' />

10
Applicazioni Web I - Web Applications I - 2022/2023
Tip: Defining Event Handlers
• Specify the name of the function return <button onClick=
{props.handler} />
prop in the event handler
return <button onClick=
{props.handler()} />
• If you need to pass parameters,
return <button onClick=
use an arrow function {props.handler(a, b)} />

return <button onClick=


{()=>props.handler()} />

return <button onClick=


{()=>props.handler(a, b)} />

11
Applicazioni Web I - Web Applications I - 2022/2023
Who Owns The State?
• Form elements are inherently stateful: they hold a value
– Input text form, selection, etc.
• React components are designed to handle the state
• The props and state are used to render the component
– To correctly render the component from the virtual DOM, React needs to know
which value must be set in the form element
– Hence, on every change (onChange) React must be notified to get the new value
and update the component state

12
Applicazioni Web I - Web Applications I - 2022/2023
Where Is The Source of Truth?
Controlled Form Components Uncontrolled Form Components
• When the React component • In some occasions, it could be
holds, in its state, the value to be useful to keep the value directly
shown in the form element, it is in the HTML form element in the
named a controlled form DOM: uncontrolled form
component component

Preferred!

13
Applicazioni Web I - Web Applications I - 2022/2023

Controlled Form Components Setting value +
onChange makes the
form component fully
controlled

React Component Render form element:


- value={x}
- onChange={changeX}
const [x, setX] = useState('') ; Form Element
x displayed as value
value={x}
changeX = (event) => {
Update
setX(event.target.value); onChange events
state
}

14
Applicazioni Web I - Web Applications I - 2022/2023
Controlled Form Component
• The event handler changes the state, setXXX() starts the update of the
virtual DOM that then updates the actual DOM content
function MyForm (props) {
handleSubmit = (event) => {
const [name, setName] = useState();
console.log('Name submitted: ' +
return <form onSubmit={handleSubmit}> name);
<label> Name: event.preventDefault();
<input type="text" value={name}
}
onChange={handleChange} />
</label>
handleChange = (event) => {
<input type="submit" value="Submit" />
setName(event.target.value) ;
</form> ;
};
}
15
Applicazioni Web I - Web Applications I - 2022/2023

Uncontrolled Form Components Not setting value +
onChange makes the
form component
uncontrolled

React Component Render Form Element


- defaultValue={props.x}
- onSubmit={submitForm}
NO
state
Form Element
x displayed as initial value

submitForm = (event) => onSubmit onChange


{
props.saveData(…);
}
Uncontrolled components
will not be described

16
Applicazioni Web I - Web Applications I - 2022/2023
Tip: Form Submission
• The onSubmit event is generated by the <form> element
• Always call event.preventDefault() to avoid the submission (and
reloading of the page)
• Perform validation of all form data before proceeding
– Using checks on state variables (on a controlled component, they contain
updated information)
– May use validator https://github.com/validatorjs/validator.js

17
Applicazioni Web I - Web Applications I - 2022/2023
Alternatives to Controlled Form Components
• Sometimes, it is tedious to use controlled form components
– Need to write an event handler for every way data can change
– Pipe all of the input state through a React component
• Alternatively, use a library such as Formik
– Keep things organized without hiding them too much
– Form state is inherently ephemeral and local: does not use state management
solutions (e.g., Redux/Flux) which would unnecessary complicate things
– Includes validation, keeping track of the visited fields, and handling form
submission
– https://jaredpalmer.com/formik
18
Applicazioni Web I - Web Applications I - 2022/2023
Tips: Handling Arrays in State
• React setXXX() with arrays requires that a new array is returned
(cannot mutate the current state)
– What is the correct way to handle arrays in React state?
• Use a new array as the value of the property
– When referencing objects, use a new object every time a property changes
• Use a callback to ensure no modifications are missed
• Typical cases -- mostly triggered by form events
– Add items
– Update items
– Remove items
https://www.robinwieruch.de/react-state-array-add-update-remove

19
Applicazioni Web I - Web Applications I - 2022/2023
Adding Items in array-valued state
// Append at the end: use .concat() // Insert value(s) at the beginning
// NO .push(): it returns the number of // use spread operator
elements, not the array
... ...

const [list, setList] = useState(['a', const [list, setList] = useState(['a',


'b', 'c']);
'b', 'c']);
... ...

setList(oldList => setList(oldList =>


return oldList.concat(newItem); return [newItem, ...oldList];
) )

https://www.robinwieruch.de/react-state-array-add-update-remove

20
Applicazioni Web I - Web Applications I - 2022/2023
Updating Items in array-valued state
// Update item: use map()
...
const [list, setList] = useState([11, 42, 32]);
...
// i is the index of the element to update
setList(oldList => {
const list = oldList.map((item, j) => {
if (j === i) {
return item + 1; // update the item
} else {
return item;
}
});
return list ;
});
https://www.robinwieruch.de/react-state-array-add-update-remove

21
Applicazioni Web I - Web Applications I - 2022/2023
Updating Items in array-of-objects state
// Update item: use map(); if items are objects, always return a new object if modified
...
const [list, setList] = useState([{id:3, val:'Foo'},{id:5, val:'Bar'}]);
...
// i is the id of the item to update
setList(oldList => {
const list = oldList.map((item) => {
if (item.id === i) {
// item.val='NewVal'; return item; // WRONG: the old object must not be reused
return {id:item.id, val:'NewVal'}; // return a new object: do not simply change content
} else {
return item;
}
});
return list ;
});

22
Applicazioni Web I - Web Applications I - 2022/2023
Removing Items in array-valued state
// Remove item: use filter() // Remove first item(s): use destructuring

...
...
const [list, setList] = useState([11, 42,
32]); const [list, setList] = useState([11, 42,
... 32]);
...

// i is the index of the element to remove


setList(oldList => {
setList(oldList=> {
return oldList.filter(
const [first, ...list] = oldList;
(item, j) => i !== j ); return list ;
}); });

https://www.robinwieruch.de/react-state-array-add-update-remove

23
Applicazioni Web I - Web Applications I - 2022/2023
Tip: Heuristics for State Lifting
• Presentational components
– Forms, Tables, Lists, Widgets, …
– Should contain local state to represent their display property
– Sort order, open/collapsed, active/paused, …
– Such state is not interesting outside the component
• Application components (or Container components)
– Manage the information and the application logic
– Usually don’t directly generate markup, generate props or context
– Most application state is “lifted up” to a Container
– Centralizes the updates, single source of State truth

24
Applicazioni Web I - Web Applications I - 2022/2023
License
• These slides are distributed under a Creative Commons license “Attribution-NonCommercial-
ShareAlike 4.0 International (CC BY-NC-SA 4.0)”
• You are free to:
– Share — copy and redistribute the material in any medium or format
– Adapt — remix, transform, and build upon the material
– The licensor cannot revoke these freedoms as long as you follow the license terms.
• Under the following terms:
– Attribution — You must give appropriate credit, provide a link to the license, and indicate if changes were
made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or
your use.
– NonCommercial — You may not use the material for commercial purposes.
– ShareAlike — If you remix, transform, or build upon the material, you must distribute your contributions
under the same license as the original.
– No additional restrictions — You may not apply legal terms or technological measures that legally restrict
others from doing anything the license permits.
• https://creativecommons.org/licenses/by-nc-sa/4.0/

25
Applicazioni Web I - Web Applications I - 2022/2023

You might also like