Last Reviewed: March 2024
Introduction
Here's a selection of templates for common JSX use-cases
Note: for myVariable > 0
below, please read "any javascript conditional expression"
. This way you can see exactly where you to place brackets in JSX. A javascript variable reference in JSX should generally be signaled by enclosing it in curly brackets. But in JSX conditional or List expressions, these are omitted (because the whole expression is already bracketed).
Also, for color: 'blue', background: 'green
please read "any series of JSX-style css properties separated by commas"
1. Conditional jsx
- Simple
{myVariable > 0 &&
< ...... jsx to be rendered when the expression evaluates as true ......>
}
- Ternary
{myVariable > 0 ?
< ...... jsx to be rendered when the expression evaluates as true ......>
:
< ...... jsx to be rendered when the expression evaluates as false ......>
}
2. Conditional styling
- Like so (activating styles optionally)
<div style={myVariable > 0 ? { color: 'blue'} : {}} />
- or (ditto for a class)
<div className={myVariable > 0 ? "displaydiv" : ""} />
- or (overwriting styles in a class)
<div className="myClass" style={myVariable > 0 ? { color: 'blue', background: 'green' } : {}} />
3. List expressions
- Simple list
{myArray.map((myArrayElement, index) => {
return (
<div key = {index}>
< ...... jsx referencing properties of myArrayElement as {myArrayElement.propertyName}......>
</div>
)
})
}
- Nested list
{myOuterArray.map((myouterArrayElement, indexOuter) => {
return (
<div key={indexOuter}>
< .. jsx referencing properties of myouterArrayElement as {myouterArrayElement.propertyName} ..>
{myouterArrayElement.arrayProperty.map((myInnerArrayElement, indexInner) => {
return (
<div key={indexInner}>
< .. jsx referencing properties of myInnerArrayElement as {myInnerArrayElement.propertyName} ..>
</div>
)
})
}
</div>
)
})
}
3. Inputs
- A simple
<input>
tag
The general practice in a React application is to ensure that your input fields are synched to the applications State by means of an onChange
function. Some neat syntax enables a singleonChange
function to obtain the name of the argument with which it is called and thus serve lots of separate inputs:
function handleChange({ target }) {
setMyState({ ...myState, [target.name]: target.value });
};
See A very Gentle Introduction to React for an explanation of how this works.
The jsx for the input field itself is just standard jsx/html, except that there wil always be a fieldname and an onChange function linking the input to the webapp's state object.
<label>My Field: </label>
<input
type="text"
name="myField"
value={myState.myField}
onChange={handleChange} />
Take care with the way you code any validation for your input. Back in the handleChange
function, the setMyState
function call is asynchronous so don't be tempted to try to validate myState.x
, say. here. This will be undefined. Use target.value
instead.
- Something more complicated - a
<select>
tag
The following code renders a <select>
tag for an array of select options defined in a myOptions array. This in turn references a handleChange
function to place a selected option in a myState
State property called "selectedOption". Initialising this in myState will determine the option initially displayed in the <select>
tag's input field
<label>Choose an Option: </label>
<select
name="selectedOption"
value={myState.selectedOption}
title="Select an Option"
onChange={handleChange}>
{myOptions.map((option) => {
return (
<option value={option} key={option}>{option}</option>
)
})
}
</select>
- a
<file>
input
A component intending to enable users to select a file from local storage (with the intention of uploading this to a host) must begin by declaring a variable (declared as fileInput
here) linked to React's userRef()
Hook function. Once a file has been selected, this constant will enable the webapp to reach into the browser's DOM and retrieve details from the current.files
array that will have been placed there (this exists as an array so that the user can select a number of files simultaneously from a folder, though in practice you'll usually be concerned only with the first element of the array)).
The component must then render an <input>
tag of type 'file' with a ref
qualifier that links it to the fileInput
variable.
This will then usually be followed by an "upload" <button>
that will launch an uploadFile()
function. See 3.4 Getting serious with Firebase V9 - Cloud Storage: Code Patterns for File Upload, Download, Delete, Fetch and Copy for an example of an uploadFile()
function.
var fileInput = React.useRef();
return(
<div>
<label> Filename : </label>
<input type='file' ref={fileInput}
accept='application/pdf'
title='Select a pdf file for this entry'
/>
<button
title='Upload this file'
onClick={uploadFile}>Upload
</button>
</div>
)
-
<radio>
buttons
A group of radio buttons are made to work cooperatively by giving their input tags a common name ('radioButtonType' in the example below). With this in place, selecting one of the buttons will then automatically de-select the last one that was selected. At the same time, the standard handleChange
function will set a State.radioButtonType
property in your State variable to the value
of the button that has been clicked.
If you wanted to pre-select a value for the button group, you would just initialise myState.radioButtonType
with that value.
<label> Type A </label>
<input type='radio'
name='radioButtonType'
value='type A'
checked={myState.radioButtonType === 'type A'}
title='Check this button to select Type A'
onChange={handleChange} />
<label> Type B </label>
<input type='radio'
name='radioButtonType'
value='type B'
checked={myState.radioButtonType === 'type B'}
title='Check this button to select Type B'
onChange={handleChange} />
- a simple
<checkbox>
The following code uses a checkbox to toggle a state variable on and off :
<label>My Checkbox</label>
<input type='checkbox'
name='myCheckbox'
value={myState.myCheckbox}
checked={myState.myCheckbox === true}
onChange={handleCheckboxChange} />
The handleCheckboxChange
function takes a specialised form, being tailored to the individual checkbox (though I'm sure somebody could come up with a generalised version using destructuring syntax):
function handleCheckboxChange() {
let myCheckbox = myState.myCheckbox;
setPopupState({ ...myState, myCheckbox: !myCheckbox })
};
- Multiple
<checkbox>
es
Checkboxes differ from radio buttons in that in this case more than one select field can be checked at a time. All you're going to get out of rendering a checkbox tag is a consistent style for rendering checkbox icons - but this is still a worthwhile saving on development time.
Each individual checkbox is now going to need its own property inside State the best way of organising this is usually to put them in an array property of State. Depending on the circumstances, you might key entries in this array on an index or a value. In the example below I've used an index.
The code below uses map to render and initialise an array of checkboxes from a myState array property called myCheckboxes. Each element in the myCheckboxes array is a boolean value that tells you whether or not the checkbox is checked. Initialising selected elements of myCheckboxes as true will "tick" those boxes in the initial display
<div>
{myState.myCheckboxes.map((checkbox, index) => {
return (
<div key={index}>
<label>Checkbox {index} : </label>
<input
type="checkbox"
name={"checkbox_" + index}
onClick={handleCheckboxChange}
defaultChecked={myState.myCheckboxes[index]} />
</div>)
})}
</div>
Again, you'll need to declare a special version of the usual handleChange
function to determine the index of the checkbox that fired the change. Once you have this, you can then toggle the setting of the appropriate myCheckboxes array entry
function handleCheckboxChange({ target }) {
// retrieve the index of the checkbox and toggle the index'th value in a new version of myCheckboxes
const indexAsString = target.name.replace('checkbox_', '');
const index = parseInt(indexAsString, 10)
const myCheckboxes = myState.myCheckboxes
myCheckboxes[index] = !myState.myCheckboxes[index]
setMyState({
...myState,
myCheckboxes: myCheckboxes
});
};
Here's a selection of templates for common JSX use-cases
Note: for myVariable > 0
below, please read "any javascript conditional expression"
. This way you can see exactly where you to place brackets in JSX. A javascript variable reference in JSX should generally be signaled by enclosing it in curly brackets. But in JSX conditional or List expressions, these are omitted (because the whole expression is already bracketed).
Also, for color: 'blue', background: 'green
please read "any series of JSX-style css properties separated by commas"
1. Conditional jsx
- Simple
{myVariable > 0 &&
< ...... jsx to be rendered when the expression evaluates as true ......>
}
- Ternary
{myVariable > 0 ?
< ...... jsx to be rendered when the expression evaluates as true ......>
:
< ...... jsx to be rendered when the expression evaluates as false ......>
}
2. Conditional styling
- Like so (activating styles optionally)
<div style={myVariable > 0 ? { color: 'blue'} : {}} />
- or (ditto for a class)
<div className={myVariable > 0 ? "displaydiv" : ""} />
- or (overwriting styles in a class)
<div className="myClass" style={myVariable > 0 ? { color: 'blue', background: 'green' } : {}} />
3. List expressions
- Simple list
{myArray.map((myArrayElement, index) => {
return (
<div key = {index}>
< ...... jsx referencing properties of myArrayElement as {myArrayElement.propertyName}......>
</div>
)
})
}
- Nested list
{myOuterArray.map((myouterArrayElement, indexOuter) => {
return (
<div key={indexOuter}>
< .. jsx referencing properties of myouterArrayElement as {myouterArrayElement.propertyName} ..>
{myouterArrayElement.arrayProperty.map((myInnerArrayElement, indexInner) => {
return (
<div key={indexInner}>
< .. jsx referencing properties of myInnerArrayElement as {myInnerArrayElement.propertyName} ..>
</div>
)
})
}
</div>
)
})
}
3. Inputs
- A simple
<input>
tag
The general practice in a React application is to ensure that your input fields are synched to the applications State by means of an onChange
function. Some neat syntax enables a singleonChange
function to obtain the name of the argument with which it is called and thus serve lots of separate inputs:
function handleChange({ target }) {
setMyState({ ...myState, [target.name]: target.value });
};
See A very Gentle Introduction to React for an explanation of how this works.
The jsx for the input field itself is just standard jsx/html, except that there wil always be a fieldname and an onChange function linking the input to the webapp's state object.
<label>My Field: </label>
<input
type="text"
name="myField"
value={myState.myField}
onChange={handleChange} />
Take care with the way you code any validation for your input. Back in the handleChange
function, the setMyState
function call is asynchronous, so don't be tempted to try to validate myState.x
here (where x
is your target name). This will be undefined.
- Something more complicated - a
<select>
tag
The following code renders a <select>
tag for an array of select options defined in a myOptions array. This in turn references a handleChange
function to place a selected option in a myState
State property called "selectedOption". Initialising this in myState will determine the option initially displayed in the <select>
tag's input field
<label>Choose an Option: </label>
<select
name="selectedOption"
value={myState.selectedOption}
title="Select an Option"
onChange={handleChange}>
{myOptions.map((option) => {
return (
<option value={option} key={option}>{option}</option>
)
})
}
</select>
- a
<file>
input
A component intending to enable users to select a file from local storage (with the intention of uploading this to a host) must begin by declaring a variable (declared as fileInput
here) linked to React's userRef()
Hook function. Once a file has been selected, this constant will enable the webapp to reach into the browser's DOM and retrieve details from the current.files
array that will have been placed there (this exists as an array so that the user can select a number of files simultaneously from a folder, though in practice you'll usually be concerned only with the first element of the array)).
The component must then render an <input>
tag of type 'file' with a ref
qualifier that links it to the fileInput
variable.
This will then usually be followed by an "upload" <button>
that will launch an uploadFile()
function. See 3.4 Getting serious with Firebase V9 - Cloud Storage: Code Patterns for File Upload, Download, Delete, Fetch and Copy for an example of an uploadFile()
function.
var fileInput = React.useRef();
return(
<div>
<label> Filename : </label>
<input type='file' ref={fileInput}
accept='application/pdf'
title='Select a pdf file for this entry'
/>
<button
title='Upload this file'
onClick={uploadFile}>Upload
</button>
</div>
)
-
<radio>
buttons
A group of radio buttons are made to work cooperatively by giving their input tags a common name ('radioButtonType' in the example below). With this in place, selecting one of the buttons will then automatically de-select the last one that was selected. At the same time, the standard handleChange
function will set a State.radioButtonType
property in your State variable to the value
of the button that has been clicked.
If you wanted to pre-select a value for the button group, you would just initialise myState.radioButtonType
with that value.
<label> Type A </label>
<input type='radio'
name='radioButtonType'
value='type A'
checked={myState.radioButtonType === 'type A'}
title='Check this button to select Type A'
onChange={handleChange} />
<label> Type B </label>
<input type='radio'
name='radioButtonType'
value='type B'
checked={myState.radioButtonType === 'type B'}
title='Check this button to select Type B'
onChange={handleChange} />
- a simple
<checkbox>
The following code uses a checkbox to toggle a state variable on and off :
<label>My Checkbox</label>
<input type='checkbox'
name='myCheckbox'
value={myState.myCheckbox}
checked={myState.myCheckbox === true}
onChange={handleCheckboxChange} />
The handleCheckboxChange
function takes a specialised form, being tailored to the individual checkbox (though I'm sure somebody could come up with a generalised version using destructuring syntax):
function handleCheckboxChange() {
let myCheckbox = myState.myCheckbox;
setPopupState({ ...myState, myCheckbox: !myCheckbox })
};
- Multiple
<checkbox>
es
Checkboxes differ from radio buttons in that in this case more than one select field can be checked at a time. All you're going to get out of rendering a checkbox tag is a consistent style for rendering checkbox icons - but this is still a worthwhile saving on development time.
Each individual checkbox is now going to need its own property inside State the best way of organising this is usually to put them in an array property of State. Depending on the circumstances, you might key entries in this array on an index or a value. In the example below I've used an index.
The code below uses map to render and initialise an array of checkboxes from a myState array property called myCheckboxes. Each element in the myCheckboxes array is a boolean value that tells you whether or not the checkbox is checked. Initialising selected elements of myCheckboxes as true will "tick" those boxes in the initial display
<div>
{myState.myCheckboxes.map((checkbox, index) => {
return (
<div key={index}>
<label>Checkbox {index} : </label>
<input
type="checkbox"
name={"checkbox_" + index}
onClick={handleCheckboxChange}
defaultChecked={myState.myCheckboxes[index]} />
</div>)
})}
</div>
Again, you'll need to declare a special version of the usual handleChange
function to determine the index of the checkbox that fired the change. Once you have this, you can then toggle the setting of the appropriate myCheckboxes array entry
function handleCheckboxChange({ target }) {
// retrieve the index of the checkbox and toggle the index'th value in a new version of myCheckboxes
const indexAsString = target.name.replace('checkbox_', '');
const index = parseInt(indexAsString, 10)
const myCheckboxes = myState.myCheckboxes
myCheckboxes[index] = !myState.myCheckboxes[index]
setMyState({
...myState,
myCheckboxes: myCheckboxes
});
};
Top comments (0)