React tutorial, part 11: dynamic markup generation and the map array method
- Transfer
- Tutorial
In today's part of the translation of the React course, we will talk about using the standard array method map () to organize the dynamic generation of JSX markup describing sets of the same type of elements.
→ Part 1: course overview, reasons for the popularity of React, ReactDOM and JSX
→ Part 2: functional components
→ Part 3: component files, project structure
→ Part 4: parent and child components
→ Part 5: starting work on a TODO application, basics of styling
→ Part 6: About some features of the course, JSX and JavaScript
→ Part 7: Inline Styles
→
Part 8: continued work on a TODO application, familiarity with the properties of components
→ Part 9: properties of components
→ Part 10: a workshop on working with properties of components and styling
→ Part 11: dynamic formation of markup and the array method map
→ Part 12: workshop, third stage towards TODO-application
→ Part 13: components based on classes
→ Part 14: workshop on the components, based on classes state components
→ Part 15: workshops to work with components state
→ Part 16: fourth stage towards TODO-attached eat, event handling
→Part 17: fifth stage of work on the TODO application, modification of the state of the components
→ Part 18: sixth stage of work on the TODO application
→ Part 19: methods of the component life cycle
→ Part 20: first lesson on conditional rendering
→ Part 21: second lesson and workshop on conditional rendering
→ Part 22: the seventh stage of working on a TODO application, loading data from external sources
→ Part 23: the first session on working with forms
→ Part 24: the second session on working with forms
→ Part 25: a workshop on working with forms
→ Part 26: application architecture, n Container / Component
→Part 27: course project
→ Original
Let's continue the work from the point where we left off, carrying out the previous practical task. Recall that then the file code
The component
Application page
Some of these components are passed properties
This file will be located in the directory of
The new file in the src folder.
In fact, it contains an array of objects. A similar array can be obtained by parsing the JSON data received from some API. We export an array from this file
Now that we have an array of source data, let's think about how to turn this data into a set of instances of React components.
Many developers say that, by mastering React, they learned JavaScript better. The reason for this is that actions like the one we are going to talk about in other frameworks, like Angular and Vue, are performed using some special means. And in React, this is done using regular javascript.
In particular, we plan to use some standard array methods that are functions of a higher order. These methods can, as arguments, take functions described by programmers. It is these functions that determine what a call to one or another standard method will do with the elements of an array.
Suppose we have a numeric array:
We can process this array using the standard array method
Check the operation of this code:
If you have not met with the methods of arrays - such as
Here we will use the method to automatically generate a list of component instances
Let's return to our example. Import the file into the
After that, in the program code, we will be able to work with an array
Notice that we pass the
From the function passed to the method
This code can be reduced if you consider two facts. First, it
The constant
What do we do now with this array of components? React makes it very convenient to work with such arrays. Namely, we are talking about the fact that such an array can be used in JSX-code. This is how the file code will now look
The application page will then look the same as before, however, the following warning can be seen in the browser console:
Its meaning boils down to the fact that the elements of the array must have a unique property
So, the property
Each object has a property
Now the code for creating an array of component instances in
If you make this change to the code, take a look at the page of the application in the browser and check the contents of the console, it turns out that the property notification
After all the transformations to which we have subjected the project, the appearance of the application page has not changed. However, the component code has
In addition, it should be noted that the core of the above code modification was the use of the standard array method
In this case, as we have said, among the standard methods of arrays you can find other interesting tools. For example, the method
If you want, you can experiment with these methods. Let's say try to use the method
Today we talked about using the standard array method
Dear readers! How would you approach the task of displaying by the App component only those instances of the Joke component whose length of the question property value exceeds the specified length?
Part 8: continued work on a TODO application, familiarity with the properties of components
→ Part 9: properties of components
→ Part 10: a workshop on working with properties of components and styling
→ Part 11: dynamic formation of markup and the array method map
→ Part 12: workshop, third stage towards TODO-application
→ Part 13: components based on classes
→ Part 14: workshop on the components, based on classes state components
→ Part 15: workshops to work with components state
→ Part 16: fourth stage towards TODO-attached eat, event handling
→Part 17: fifth stage of work on the TODO application, modification of the state of the components
→ Part 18: sixth stage of work on the TODO application
→ Part 19: methods of the component life cycle
→ Part 20: first lesson on conditional rendering
→ Part 21: second lesson and workshop on conditional rendering
→ Part 22: the seventh stage of working on a TODO application, loading data from external sources
→ Part 23: the first session on working with forms
→ Part 24: the second session on working with forms
→ Part 25: a workshop on working with forms
→ Part 26: application architecture, n Container / Component
→Part 27: course project
Lesson 21: Dynamic Markup Formation and the Map Array Method
→ Original
Let's continue the work from the point where we left off, carrying out the previous practical task. Recall that then the file code
App.js
looked like this:import React from"react"import Joke from"./Joke"functionApp() {
return (
<div>
<Joke punchLine="It’s hard to explain puns to kleptomaniacs because they always take things literally." />
<Joke
question="What's the best thing about Switzerland?"
punchLine="I don't know, but the flag is a big plus!"
/>
<Joke
question="Did you hear about the mathematician who's afraid of negative numbers?"
punchLine="He'll stop at nothing to avoid them!"
/>
<Joke
question="Hear about the new restaurant called Karma?"
punchLine="There’s no menu: You get what you deserve."
/>
<Joke
question="Did you hear about the actor who fell through the floorboards?"
punchLine="He was just going through a stage."
/>
<Joke
question="Did you hear about the claustrophobic astronaut?"
punchLine="He just needed a little space."
/>
</div>
)
}
export default App
The component
App
displays a set of components Joke
. Here’s how the application page looks like at this stage.Application page
Some of these components are passed properties
question
andpunchLine
, and some - onlypunchLine
. Now the values of these properties are specified in the code for creating component instancesJoke
as plain text. In reality, the bulk of the data that is displayed on the React-application pages, enters the application as a result of HTTP requests to certain APIs. These APIs are supported by server facilities that take information from databases, format it as JSON code, and send this code to client parts of applications. We have not yet reached such a level to perform requests to the API, so now we, in the role of the data source, will use the file with the data that could be obtained as a result of parsing the server's JSON response. Namely, it will be a filejokesData.js
with the following content:const jokesData = [
{
id: 1,
punchLine: "It’s hard to explain puns to kleptomaniacs because they always take things literally."
},
{
id: 2,
question: "What's the best thing about Switzerland?",
punchLine: "I don't know, but the flag is a big plus!"
},
{
id: 3,
question: "Did you hear about the mathematician who's afraid of negative numbers?",
punchLine: "He'll stop at nothing to avoid them!"
},
{
id: 4,
question: "Hear about the new restaurant called Karma?",
punchLine: "There’s no menu: You get what you deserve."
},
{
id: 5,
question: "Did you hear about the actor who fell through the floorboards?",
punchLine: "He was just going through a stage."
},
{
id: 6,
question: "Did you hear about the claustrophobic astronaut?",
punchLine: "He just needed a little space."
}
]
exportdefault jokesData
This file will be located in the directory of
src
our project.The new file in the src folder.
In fact, it contains an array of objects. A similar array can be obtained by parsing the JSON data received from some API. We export an array from this file
jokesData
. If necessary, we can import this file into the component in which it is needed, and imagine that we are not working with data taken from the file, but with what returned to us some kind of API. Now that we have an array of source data, let's think about how to turn this data into a set of instances of React components.
Many developers say that, by mastering React, they learned JavaScript better. The reason for this is that actions like the one we are going to talk about in other frameworks, like Angular and Vue, are performed using some special means. And in React, this is done using regular javascript.
In particular, we plan to use some standard array methods that are functions of a higher order. These methods can, as arguments, take functions described by programmers. It is these functions that determine what a call to one or another standard method will do with the elements of an array.
Suppose we have a numeric array:
const nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
We can process this array using the standard array method
map()
, passing it a certain function that specifies the order of conversion of the elements of this array. In our case, this function will be transferred, one by one, numbers from this array. A function can do anything with them, after which what it returns will fall into a new array, into an element whose index corresponds to the index of the element being processed. If we need to create a new array, whose elements are elements of the original array, multiplied by 2, then it will look like this:const doubled = nums.map(function(num) {
return num * 2
})
Check the operation of this code:
console.log(doubled) // [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
If you have not met with the methods of arrays - such as
map()
, filter()
, reduce()
and others - it is recommended to deal with them. Here we will use the method to automatically generate a list of component instances
map()
. Let's return to our example. Import the file into the
App.js
file jokesData.js
. This is done like this:import jokesData from"./jokesData"
After that, in the program code, we will be able to work with an array
jokesData
. Namely, we are going to use the method map()
. Here is what the “blank” of this method will look like.jokesData.map(joke => {
})
Notice that we pass the
map()
arrow function to the method . In our case, this allows us to make the code more compact. Since the function takes only one parameter ( joke
), we, when it is declared, can do without parentheses. From the function passed to the method
map()
, we want to return a new instance of the component Joke
to which the properties question
and the punchLine
array element received in it are transferred jokesData
. Here is what it might look like:jokesData.map(joke => {
return (
<Jokequestion={joke.question}punchLine={joke.punchLine} />
)
})
This code can be reduced if you consider two facts. First, it
return
returns only one element, so you can put this element immediately after return
, getting rid of the parentheses. Secondly, the switch function contains only the operation of returning a certain value, therefore, when declaring such a function, you can do without a keyword return
and without curly brackets. In addition, recall that as a result of the method map()
, a new array is formed. This array needs to be saved somewhere. All these considerations lead us to the following:const jokeComponents = jokesData.map(joke => <Joke question={joke.question} punchLine={joke.punchLine} />)
The constant
jokeComponents
will now contain an array, each element of which is a description of the component instance Joke
with the properties passed to it question
and punchLine
. What do we do now with this array of components? React makes it very convenient to work with such arrays. Namely, we are talking about the fact that such an array can be used in JSX-code. This is how the file code will now look
App
:import React from"react"import Joke from"./Joke"import jokesData from"./jokesData"functionApp() {
const jokeComponents = jokesData.map(joke => <Joke question={joke.question} punchLine={joke.punchLine} />)
return (
<div>
{jokeComponents}
</div>
)
}
exportdefault App
The application page will then look the same as before, however, the following warning can be seen in the browser console:
Warning: Each child in an array or iterator should have a unique "key" prop.
Check the render method of`App`. See https://fb.me/react-warning-keys for more information.
in Joke (at App.js:7)
in App (at src/index.js:6)
Its meaning boils down to the fact that the elements of the array must have a unique property
key
. We will not go into details as to why React expects a unique property key
for repeating components. It is enough for us to take into account the fact that when performing mass creation of instances of components, like the one we just performed using the method map()
, we need to pass a property to the instances key
. In this case, such a property can be passed both to the component instance itself, and, for example, to the tag containing the <div>
component code. It does not play a special role. So, the property
key
must be assigned some unique value. As a rule, in the data objects obtained from the API, there are some identifiers (properties likeid
). The main thing for us is their uniqueness. For example, we could assign a property a key
value joke.question
— all the texts in these properties in our application are unique. But we will do otherwise. Recall how objects with data from the array that we exported from a file look like jokesData.js
. Here is his fragment:const jokesData = [
{
id: 1,
punchLine: "It’s hard to explain puns to kleptomaniacs because they always take things literally."
},
{
id: 2,
question: "What's the best thing about Switzerland?",
punchLine: "I don't know, but the flag is a big plus!"
},
...
]
Each object has a property
id
, the uniqueness of which we maintain on our own. It is the values of such properties that can be used as values for a property key
. Now the code for creating an array of component instances in
App.js
will take the following form:const jokeComponents = jokesData.map(joke => <Joke key={joke.id} question={joke.question} punchLine={joke.punchLine} />)
If you make this change to the code, take a look at the page of the application in the browser and check the contents of the console, it turns out that the property notification
key
disappeared. After all the transformations to which we have subjected the project, the appearance of the application page has not changed. However, the component code has
App
become much shorter and clearer, and the data to form the list of components is now taken from something that strongly resembles an external data source. It is under this scheme that real applications work. In addition, it should be noted that the core of the above code modification was the use of the standard array method
map()
. We used the method of generating a list of component instances Joke
in the component.App
, but nothing prevents us, if necessary, from taking the same approach in a component Joke
that can, based on the data passed to it, form its own list of instances of a certain component. In this case, as we have said, among the standard methods of arrays you can find other interesting tools. For example, the method
sort()
can be used to sort the elements of an array according to a certain attribute. The method filter()
can be used to select only those elements of the array that meet certain criteria. All this applies to working with arrays containing instances of components. If you want, you can experiment with these methods. Let's say try to use the method
filter()
and remove from the output formed by the componentApp
, those component instances Joke
whose property question
does not exceed the specified length. Or do so in conclusion would get only the components that are set and the property question
, and the property punchLine
.Results
Today we talked about using the standard array method
map()
to generate lists of components, and also discussed the possibilities that other standard array methods give us. The next time you are waiting for a practical lesson on the material studied today. Dear readers! How would you approach the task of displaying by the App component only those instances of the Joke component whose length of the question property value exceeds the specified length?