137 lines
4 KiB
Markdown
137 lines
4 KiB
Markdown
---
|
|
tags:
|
|
- javascript
|
|
- react
|
|
---
|
|
|
|
# Iterating through data
|
|
|
|
As React follows the **functional programming paradigm** and state versioning,
|
|
looping is not the recommended way of engineering repeated processes since it
|
|
presupposes pre-existing state. Instead React relies on the functional methods
|
|
of modern JavaScript such as `map` , `filter` , `reduce` to output the values of
|
|
iterative data structures.
|
|
|
|
Instead of mutating the state of a reference type, these methods are
|
|
'non-destructive': they create a new array that meets the requirements set in
|
|
the particular method. These newly created arrays and objects therefore form the
|
|
basis of the state versioning, because each new array that is engendered, is a
|
|
new state configuration.
|
|
|
|
## The `key` attribute
|
|
|
|
The `key` attribute is a special React attribute that should be added to the
|
|
elements of any listed content (i.e numbered lists, unordered lists, `select`
|
|
options etc; basically anything rendered that comes about through mapping arrays
|
|
and objects).
|
|
|
|
This enables React to monitor the state of the list: which items have changed,
|
|
been added, or removed.
|
|
|
|
The best way to pick a key is to use a string that uniquely identifies a list
|
|
item among its siblings.
|
|
|
|
For instance, using our earlier `numbers` array, assuming each number is unique,
|
|
we could use the number itself as the key:
|
|
|
|
```jsx
|
|
const numbers = [1, 2, 3, 4, 5];
|
|
const listItems = numbers.map((number) => (
|
|
<li key={number.toString()}> {number}</li>
|
|
));
|
|
```
|
|
|
|
> Keys have to be unique to the individual element and not shared by any other
|
|
> sibling. But they do not need to be globally unique. You could use the same
|
|
> `key` name in another array list.
|
|
|
|
> Keys should be string types, not other data types. You can use the
|
|
> `.toString()` method to ensure this is the case.
|
|
|
|
If you can't find a unique basis for naming a series of keys, you can use the
|
|
`index` value of the `Array.map` function. This should only be used if the order
|
|
of the items doesn't change. An example:
|
|
|
|
```jsx
|
|
class List extends React.Component {
|
|
render() {
|
|
const demoArr = ["cat", "dog", "mouse"];
|
|
return (
|
|
<ul>
|
|
{demoArr.map((x, index) => (
|
|
<li key={index}>{x}</li>
|
|
))}
|
|
</ul>
|
|
</div>
|
|
);
|
|
}
|
|
}
|
|
```
|
|
|
|
## Demonstration
|
|
|
|
### Source data
|
|
|
|
```jsx
|
|
const blogData = [
|
|
{
|
|
id: 1,
|
|
date: "2020-11-15",
|
|
shortByline:
|
|
"Quisque cursus, metus vitae pharetra auctor, sem massa mattis sem, at interdum magna augue eget diam. ",
|
|
longByline:
|
|
"Quisque cursus, metus vitae pharetra auctor, sem massa mattis sem, at interdum magna augue eget diam. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Morbi lacinia molestie dui. Praesent blandit dolor.",
|
|
image: blogImage,
|
|
},
|
|
{
|
|
id: 2,
|
|
date: "2020-08-11",
|
|
shortByline:
|
|
"Quisque cursus, metus vitae pharetra auctor, sem massa mattis sem, at interdum magna augue eget diam. ",
|
|
longByline:
|
|
"Quisque cursus, metus vitae pharetra auctor, sem massa mattis sem, at interdum magna augue eget diam. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Morbi lacinia molestie dui. Praesent blandit dolor.",
|
|
image: blogImage,
|
|
},
|
|
];
|
|
```
|
|
|
|
### Child component
|
|
|
|
```jsx
|
|
export default function BlogPreviewCard(props) {
|
|
return (
|
|
<Card>
|
|
<CardMedia image={props.image} />
|
|
<CardContent>
|
|
<Typography>{props.date}</Typography>
|
|
<Typography>{props.title}</Typography>
|
|
<Typography>{props.shortByline}</Typography>
|
|
</CardContent>
|
|
<CardActions>
|
|
<Button>Read</Button>
|
|
</CardActions>
|
|
</Card>
|
|
);
|
|
}
|
|
```
|
|
|
|
### Iteration
|
|
|
|
```jsx
|
|
// This uses the Material-UI grid component
|
|
|
|
import BlogPreviewCard from "../components/BlogPreviewCard"
|
|
import blogData from "../data/blogData
|
|
|
|
export default function BlogPreviewSet() {
|
|
return (
|
|
<Grid>
|
|
{blogDummyData.map((data, index) => (
|
|
<Grid key={index}>
|
|
<BlogPreviewCard key={index} {...data} />
|
|
</Grid>
|
|
))}
|
|
</Grid>
|
|
)
|
|
}
|
|
```
|