What you'll learn:
alertNow, let’s make the radio group functional!
By adding the selected attribute to our <Radio> inside RadioGroup all our radios are selected.
function RadioGroup({ choices, ...props }) {
return (
<Frame background={null} {...props}>
{choices.map(choice => (
<Radio selected key={choice}>{choice}</Radio>
))}
</Frame>
)
}
However, we don’t want everything to be selected. We only want one <Radio> to be selected at a time and the rest not with the values true and false respectively. Essentially, we want to have a changing value where ??? is.
function RadioGroup({ choices, ...props }) {
return (
<Frame background={null} {...props}>
{choices.map(choice => (
<Radio selected={???} key={choice}>{choice}</Radio>
))}
</Frame>
)
}
Let’s decide what these question marks should be.
Since map is a function, specifically an arrow function, we can add another parameter.
Our only parameter currently in our arrow function is choice, so to add another parameter we have to insert a surrounding pair of parentheses.
function RadioGroup({ choices, ...props }) {
return (
<Frame background={null} {...props}>
{choices.map((choice, index) => (
<Radio selected={???} key={choice}>{choice}</Radio>
))}
</Frame>
)
}
We are going to use index to store the index of each element in the choices array. If we print out index, we’ll see 0, 1, 2 correspond with element 1, 2, 3 and so on.
Our solution involves comparing the selected index to the choices element index. Therefore, we need to define a new variable: selectedIndex.
function RadioGroup({ choices, ...props }) {
let selectedIndex = 2
return (
<Frame background={null} {...props}>
{choices.map((choice, index) => (
<Radio selected={index===selectedIndex} key={choice}>{choice}</Radio>
))}
</Frame>
)
}
We are comparing the choices index to selectedIndex in a boolean comparison that will give us a true or false. Take note that each <Radio> has its own individual onClick function and index. Therefore, when we click on a certain Radio, we can compare its index to our selectedIndex.
Keep in mind, in JavaScript, if we want to test if two things are equal, we use three equal signs.
Since our selectedIndex = 2, the third radio is selected by array conventions.
onClickNow, all we need to do is change the value of selectedIndex when a Radio is clicked.
Let's add onClick to our <Radio> tag. To test if onClick is being called, we can use the alert function which will show a popup dialog, similar to the functionality of console.log.
<Frame background={null} {...props}>
{choices.map((choice, index) => (
<Radio
selected={index===selectedIndex}
key={choice}
onClick={function() {
// change selectedIndex
alert("clicked)
}}>
{choice}
</Radio>
))}
</Frame>
However, we don’t see a dialog. This means onClick does not work yet.
Why?
Because our Radio component doesn’t know about onClick yet! For onClick to be functional, we need to set it on one of the Frames.
What can we use to add all the properties of <Radio> to our <Frame>?
The spread operator!
function Radio(props) {
return (
<Frame
position="relative"
size="auto"
style={{ display: "flex", marginBottom: 10 }}
background="null"
{...props}
>
...
)
}
If we remove the alert now and try to change selectedIndex like this will it work?
<Frame background={null} {...props}>
{choices.map((choice, index) => (
<Radio
selected={index===selectedIndex}
key={choice}
onClick={function() {
// change selectedIndex
selectedIndex = 5
}}>
{choice}
</Radio>
))}
</Frame>
It doesn’t!
Remember, React components are like printers!
We cannot simply change a snapshot if it’s already printed. We have to print a new page.
Our first snapshot looks similar to this:
If we want to change what is shown in our preview, we have to print out a new page:
useStateWe can utilize useState to print a new page.
function RadioGroup({ choices, ...props }) {
let [selectedIndex, setSelectedIndex] = React.useState(0)
return(
...
)
}
To change selectedIndex in our onClick function, we just have to call setSelectedIndex.
<Frame background={null} {...props}>
{choices.map((choice, index) => (
<Radio
selected={index===selectedIndex}
key={choice}
onClick={function() {
// change selectedIndex
setSelectedIndex(index)
}}>
{choice}
</Radio>
))}
</Frame>
We now have a fully functional radio group that we built from scratch!
The radio group module is finished! Along the way we learned how to create a counter and about React snapshots, React States, useState, rendering, coding tips, code efficiency, the spread operator, and more!
In the next post, we'll go back to our toggle and truly understand what useCycle is.