Introduction
- Components in reactjs act like functions in js, but they operate independently and are responsible for returning html components through
render
function. - There are 2 types of components: Function component and Class component
Function and Class Components
Function Component
In ReactJS, the easiest way to define a component is to write a JavaScript function, with the response returned as html:
1 2 3 4 | <span class="token keyword">function</span> <span class="token function">Welcome</span> <span class="token punctuation">(</span> <span class="token parameter">props</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token operator"><</span> h1 <span class="token operator">></span> Hello <span class="token punctuation">,</span> <span class="token punctuation">{</span> props <span class="token punctuation">.</span> name <span class="token punctuation">}</span> <span class="token operator"><</span> <span class="token operator">/</span> h1 <span class="token operator">></span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> |
This is also the way to define a Function component
Class Component
We can also use ES6 Class
to define a component, this is called Class component in ReactJS:
1 2 3 4 5 6 | <span class="token keyword">class</span> <span class="token class-name">Welcome</span> <span class="token keyword">extends</span> <span class="token class-name">React <span class="token punctuation">.</span> Component</span> <span class="token punctuation">{</span> <span class="token function">render</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token operator"><</span> h1 <span class="token operator">></span> Hello <span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token keyword">this</span> <span class="token punctuation">.</span> props <span class="token punctuation">.</span> name <span class="token punctuation">}</span> <span class="token operator"><</span> <span class="token operator">/</span> h1 <span class="token operator">></span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
Both components in the example above return the same html response.
Rendering a Component
The React element not only represents the DOM tag, we can also use it to represent self-defined components:
1 2 | <span class="token keyword">const</span> element <span class="token operator">=</span> <span class="token operator"><</span> Welcome name <span class="token operator">=</span> <span class="token string">"Thanos"</span> <span class="token operator">/</span> <span class="token operator">></span> <span class="token punctuation">;</span> |
When React detects that an element is a self-defined component, it will pass JSX attributes to that component, and we call these attributes props
:
1 2 3 4 5 6 7 8 9 10 | <span class="token keyword">function</span> <span class="token function">Welcome</span> <span class="token punctuation">(</span> <span class="token parameter">props</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token operator"><</span> h1 <span class="token operator">></span> Hello <span class="token punctuation">,</span> <span class="token punctuation">{</span> props <span class="token punctuation">.</span> name <span class="token punctuation">}</span> <span class="token operator"><</span> <span class="token operator">/</span> h1 <span class="token operator">></span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">const</span> element <span class="token operator">=</span> <span class="token operator"><</span> Welcome name <span class="token operator">=</span> <span class="token string">"Thanos"</span> <span class="token operator">/</span> <span class="token operator">></span> <span class="token punctuation">;</span> ReactDOM <span class="token punctuation">.</span> <span class="token function">render</span> <span class="token punctuation">(</span> element <span class="token punctuation">,</span> document <span class="token punctuation">.</span> <span class="token function">getElementById</span> <span class="token punctuation">(</span> <span class="token string">'root'</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> |
Let’s look at the example above:
- We made the
ReactDOM.render()
call to the<Welcome name="Thanos" />
element - React will call the
Welcome
component withprops
as{name="Thanos"}
- Component
Welcome
will return html response:<h1>Hello, Thanos</h1>
- The React DOM takes care of the rest, which is to update the corresponding DOM to match the html response from Component
Welcome
Note that React will distinguish DOM tags and Component by the first letter, if written in lower case it will be DOM tags (eg <div />
), and if the first capital letter will be component (ex: <Welcome />
). So component names always have to start with capital letters.
Composing Components
Components can refer to each other on their output. This makes it possible to combine and customize components, for example a component rendering to many other components:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <span class="token keyword">function</span> <span class="token function">Welcome</span> <span class="token punctuation">(</span> <span class="token parameter">props</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token operator"><</span> h1 <span class="token operator">></span> Hello <span class="token punctuation">,</span> <span class="token punctuation">{</span> props <span class="token punctuation">.</span> name <span class="token punctuation">}</span> <span class="token operator"><</span> <span class="token operator">/</span> h1 <span class="token operator">></span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">function</span> <span class="token function">App</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> <span class="token operator"><</span> div <span class="token operator">></span> <span class="token operator"><</span> Welcome name <span class="token operator">=</span> <span class="token string">"Thanos"</span> <span class="token operator">/</span> <span class="token operator">></span> <span class="token operator"><</span> Welcome name <span class="token operator">=</span> <span class="token string">"Thor"</span> <span class="token operator">/</span> <span class="token operator">></span> <span class="token operator"><</span> Welcome name <span class="token operator">=</span> <span class="token string">"Iron Man"</span> <span class="token operator">/</span> <span class="token operator">></span> <span class="token operator"><</span> <span class="token operator">/</span> div <span class="token operator">></span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> ReactDOM <span class="token punctuation">.</span> <span class="token function">render</span> <span class="token punctuation">(</span> <span class="token operator"><</span> App <span class="token operator">/</span> <span class="token operator">></span> <span class="token punctuation">,</span> document <span class="token punctuation">.</span> <span class="token function">getElementById</span> <span class="token punctuation">(</span> <span class="token string">'root'</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> |
Extracting Components
A component can be divided into many different small components within it. Consider the example below, we define a function component Comment
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | <span class="token keyword">function</span> <span class="token function">Comment</span> <span class="token punctuation">(</span> <span class="token parameter">props</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> <span class="token operator"><</span> div className <span class="token operator">=</span> <span class="token string">"Comment"</span> <span class="token operator">></span> <span class="token operator"><</span> div className <span class="token operator">=</span> <span class="token string">"UserInfo"</span> <span class="token operator">></span> <span class="token operator"><</span> img className <span class="token operator">=</span> <span class="token string">"Avatar"</span> src <span class="token operator">=</span> <span class="token punctuation">{</span> props <span class="token punctuation">.</span> author <span class="token punctuation">.</span> avatarUrl <span class="token punctuation">}</span> alt <span class="token operator">=</span> <span class="token punctuation">{</span> props <span class="token punctuation">.</span> author <span class="token punctuation">.</span> name <span class="token punctuation">}</span> <span class="token operator">/</span> <span class="token operator">></span> <span class="token operator"><</span> div className <span class="token operator">=</span> <span class="token string">"UserInfo-name"</span> <span class="token operator">></span> <span class="token punctuation">{</span> props <span class="token punctuation">.</span> author <span class="token punctuation">.</span> name <span class="token punctuation">}</span> <span class="token operator"><</span> <span class="token operator">/</span> div <span class="token operator">></span> <span class="token operator"><</span> <span class="token operator">/</span> div <span class="token operator">></span> <span class="token operator"><</span> div className <span class="token operator">=</span> <span class="token string">"Comment-text"</span> <span class="token operator">></span> <span class="token punctuation">{</span> props <span class="token punctuation">.</span> text <span class="token punctuation">}</span> <span class="token operator"><</span> <span class="token operator">/</span> div <span class="token operator">></span> <span class="token operator"><</span> div className <span class="token operator">=</span> <span class="token string">"Comment-date"</span> <span class="token operator">></span> <span class="token punctuation">{</span> <span class="token function">formatDate</span> <span class="token punctuation">(</span> props <span class="token punctuation">.</span> date <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token operator"><</span> <span class="token operator">/</span> div <span class="token operator">></span> <span class="token operator"><</span> <span class="token operator">/</span> div <span class="token operator">></span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> |
the props above include author
as object, text
string, and date
date. With Components with nested props as above, it is often difficult to change logic or reuse internal components. We can split html tags into corresponding child components.
The first will be Avatar
:
1 2 3 4 5 6 7 8 9 | <span class="token keyword">function</span> <span class="token function">Avatar</span> <span class="token punctuation">(</span> <span class="token parameter">props</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> <span class="token operator"><</span> img className <span class="token operator">=</span> <span class="token string">"Avatar"</span> src <span class="token operator">=</span> <span class="token punctuation">{</span> props <span class="token punctuation">.</span> user <span class="token punctuation">.</span> avatarUrl <span class="token punctuation">}</span> alt <span class="token operator">=</span> <span class="token punctuation">{</span> props <span class="token punctuation">.</span> user <span class="token punctuation">.</span> name <span class="token punctuation">}</span> <span class="token operator">/</span> <span class="token operator">></span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> |
Since we split Avatar
into a separate component that is not only used in the Comment
component, the props name is not necessarily author
. When separating the component for reuse in multiple places, it’s better to name the props that match the component’s functionality rather than the context in which the component is being used.
Now the Comment
component will be shortened a bit:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <span class="token keyword">function</span> <span class="token function">Comment</span> <span class="token punctuation">(</span> <span class="token parameter">props</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> <span class="token operator"><</span> div className <span class="token operator">=</span> <span class="token string">"Comment"</span> <span class="token operator">></span> <span class="token operator"><</span> div className <span class="token operator">=</span> <span class="token string">"UserInfo"</span> <span class="token operator">></span> <span class="token operator"><</span> Avatar user <span class="token operator">=</span> <span class="token punctuation">{</span> props <span class="token punctuation">.</span> author <span class="token punctuation">}</span> <span class="token operator">/</span> <span class="token operator">></span> <span class="token operator"><</span> div className <span class="token operator">=</span> <span class="token string">"UserInfo-name"</span> <span class="token operator">></span> <span class="token punctuation">{</span> props <span class="token punctuation">.</span> author <span class="token punctuation">.</span> name <span class="token punctuation">}</span> <span class="token operator"><</span> <span class="token operator">/</span> div <span class="token operator">></span> <span class="token operator"><</span> <span class="token operator">/</span> div <span class="token operator">></span> <span class="token operator"><</span> div className <span class="token operator">=</span> <span class="token string">"Comment-text"</span> <span class="token operator">></span> <span class="token punctuation">{</span> props <span class="token punctuation">.</span> text <span class="token punctuation">}</span> <span class="token operator"><</span> <span class="token operator">/</span> div <span class="token operator">></span> <span class="token operator"><</span> div className <span class="token operator">=</span> <span class="token string">"Comment-date"</span> <span class="token operator">></span> <span class="token punctuation">{</span> <span class="token function">formatDate</span> <span class="token punctuation">(</span> props <span class="token punctuation">.</span> date <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token operator"><</span> <span class="token operator">/</span> div <span class="token operator">></span> <span class="token operator"><</span> <span class="token operator">/</span> div <span class="token operator">></span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> |
For more convenience, we will separate the UserInfo
part into a separate component, and render the Avatar
component inside it:
1 2 3 4 5 6 7 8 9 10 11 | <span class="token keyword">function</span> <span class="token function">UserInfo</span> <span class="token punctuation">(</span> <span class="token parameter">props</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> <span class="token operator"><</span> div className <span class="token operator">=</span> <span class="token string">"UserInfo"</span> <span class="token operator">></span> <span class="token operator"><</span> Avatar user <span class="token operator">=</span> <span class="token punctuation">{</span> props <span class="token punctuation">.</span> user <span class="token punctuation">}</span> <span class="token operator">/</span> <span class="token operator">></span> <span class="token operator"><</span> div className <span class="token operator">=</span> <span class="token string">"UserInfo-name"</span> <span class="token operator">></span> <span class="token punctuation">{</span> props <span class="token punctuation">.</span> user <span class="token punctuation">.</span> name <span class="token punctuation">}</span> <span class="token operator"><</span> <span class="token operator">/</span> div <span class="token operator">></span> <span class="token operator"><</span> <span class="token operator">/</span> div <span class="token operator">></span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> |
Now the Comment
component is pretty neat, and the UserInfo
component can be reused wherever we want:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <span class="token keyword">function</span> <span class="token function">Comment</span> <span class="token punctuation">(</span> <span class="token parameter">props</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">(</span> <span class="token operator"><</span> div className <span class="token operator">=</span> <span class="token string">"Comment"</span> <span class="token operator">></span> <span class="token operator"><</span> UserInfo user <span class="token operator">=</span> <span class="token punctuation">{</span> props <span class="token punctuation">.</span> author <span class="token punctuation">}</span> <span class="token operator">/</span> <span class="token operator">></span> <span class="token operator"><</span> div className <span class="token operator">=</span> <span class="token string">"Comment-text"</span> <span class="token operator">></span> <span class="token punctuation">{</span> props <span class="token punctuation">.</span> text <span class="token punctuation">}</span> <span class="token operator"><</span> <span class="token operator">/</span> div <span class="token operator">></span> <span class="token operator"><</span> div className <span class="token operator">=</span> <span class="token string">"Comment-date"</span> <span class="token operator">></span> <span class="token punctuation">{</span> <span class="token function">formatDate</span> <span class="token punctuation">(</span> props <span class="token punctuation">.</span> date <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token operator"><</span> <span class="token operator">/</span> div <span class="token operator">></span> <span class="token operator"><</span> <span class="token operator">/</span> div <span class="token operator">></span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> |
Props are Read-Only
No matter how you instantiate the component to a function or class type, the component never changes its own props. While ReactJS is quite flexible, it has a general rule of thumb that “All components must be pure functions, must not change input values and output must always be of the same format” . So we should use props for which components that always show the same output for the same input, which makes it easier for them to control it.
But data in the UI is usually dynamic and changes continuously over time, in case we want to change the output of the component corresponding to the response, we will learn about State
in the next article.
Summary
Posts are intended to share about Components and Props in reactJS. Thank you for your time.