diff --git a/docs/ui/react/components.md b/docs/ui/react/components.md index 5689234..0d0eb58 100644 --- a/docs/ui/react/components.md +++ b/docs/ui/react/components.md @@ -25,9 +25,594 @@ permalink: /docs/ui/react/components/ ## React Components -Components are the building blocks of any React app and a typical React app will have many of these. Simply put, a component is a JavaScript class or function that optionally accepts inputs i.e. properties(props) and returns a React element that describes how a section of the UI (User Interface) should appear. -In React, a Stateful Component is a component that holds some state. A Stateless component, by contrast, has no state. Note that both types of components can use props. +Components are the building blocks of any React app and a typical React app will have many of these. Simply put, a component is a JavaScript class or function that optionally accepts inputs i.e. properties(`props`) and returns a React element that describes how a section of the UI (User Interface) should appear. + +In React, a **Stateful Component** is a component that holds some state. A **Stateless component**, by contrast, has no state. Note that both types of components can use props. + + +**1. Stateless Component:** + +```js +import React from 'react' + +const ExampleComponent = (props) => { + return

Stateless Component - {props.message}

; +}; + +const App = () => { + const message = 'React Interview Questions' + return ( +
+ +
+ ); +}; + +export default App; +``` + +The above example shows a stateless component named ExampleComponent which is inserted in the `` component. The `ExampleComponent` just comprises of a `

` element. Although the **Stateless component** has no state, it still receives data via props from a parent component. + +**2. Stateful Component:** + +```js +import React, { useState } from 'react' + +const ExampleComponent = (props) => { + const [email, setEmail] = useState(props.defaultEmail) + + const changeEmailHandler = (e) => { + setEmail(e.target.value) + } + + return ( + + ); +} + + +const App = () => { + const defaultEmail = "suniti.mukhopadhyay@gmail.com" + return ( +
+ +
+ ); +}; + +export default App; +``` + +The above example shows a stateful component named **ExampleComponent** which is inserted in the `` component. The **ExampleComponent** contains a ``. First of all, in the **ExampleComponent**, we need to assign **defaultEmail** by props to a local **state** by a `useState()` hook in **ExampleComponent**. + +Next, we have to pass **email** to **value** property of a input tag and pass a function **changeEmailHandler** to an `onChange()` event for a purpose keeping track of the current value of the input. + + +### Component and Container + +The **presentational** components are concerned with the look, **container** components are concerned with making things work. + +For example, this is a presentational component. It gets data from its props, and just focuses on showing an element + +```js +/** + * Presentational Component + */ +const Users = props => ( +
    + {props.users.map(user => ( +
  • {user}
  • + ))} +
+) +``` + +On the other hand this is a container component. It manages and stores its own data, and uses the presentational component to display it. + +```js +/** + * Container Component + */ +class UsersContainer extends React.Component { + constructor() { + this.state = { + users: [] + } + } + + componentDidMount() { + axios.get('/users').then(users => + this.setState({ users: users })) + ) + } + + render() { + return + } +} +``` + + +### import and export components + +```js +// Importing combination +import React, { Component } from 'react'; +import ReactDOM from 'react-dom'; + +// Wrapping components with braces if no default exports +import { Button } from './Button'; + +// Default exports ( recommended ) +import Button from './Button'; + +class DangerButton extends Component { + render() + { + return + ); +} +``` + + + + +### revent a component from rendering? + +React **shouldComponentUpdate()** is a performance optimization method, and it tells React to avoid re-rendering a component, even if state or prop values may have changed. This method only used when a component will stay static or pure. + +The React `shouldComponentUpdate()` method return `true` if it needs to re-render or `false` to avoid being re-render. + +**Syntax:** + +```js +shouldComponentUpdate(nextProps, nextState){ } +``` + +**Example:** + +```js +/** + * Prevent a component from rendering + */ +export default class App extends React.Component { + constructor() { + super(); + this.state = { + countOfClicks: 0 + }; + this.handleClick = this.handleClick.bind(this); + } + + handleClick() { + this.setState({ + countOfClicks: this.state.countOfClicks + 1 + }); + } + + shouldComponentUpdate(nextProps, nextState) { + console.log("this.state.countOfClicks", this.state.countOfClicks); + console.log("nextState.countOfClicks", nextState.countOfClicks); + return true; + } + + render() { + return ( +
+

shouldComponentUpdate Example

+

Count of clicks: {this.state.countOfClicks}

+ +
+ ); + } +} +``` + + +### use StrictMode component + +The **StrictMode** is a tool for highlighting potential problems in an application. Like `Fragment`, `StrictMode` does not render any visible UI. It activates additional checks and warnings for its descendants. + +Strict mode checks are run in development mode only; they do not impact the production build. + +**Example:** + +```js +/** + * StrictMode + */ +import { StrictMode } from "react"; +import MyComponent from "./MyComponent"; + +export default function App() { + return ( + + + + ); +} +``` + +React StrictMode, in order to be efficient and avoid potential problems by any side-effects, needs to trigger some methods and lifecycle hooks twice. These are: + +* Class component constructor() method +* The render() method +* setState() updater functions (the first argument) +* The static getDerivedStateFromProps() lifecycle +* React.useState() function + +**Benefits of StrictMode:** + +* Identifying components with unsafe lifecycles +* Warning about legacy string ref API usage +* Warning about deprecated findDOMNode usage +* Detecting unexpected side effects +* Detecting legacy context API + + + +### avoid using setState() after a component has been unmounted? + +Calling `setState()` after a component has unmounted will emit a warning. The "setState warning" exists to help you catch bugs, because calling `setState()` on an unmounted component is an indication that your app/component has somehow failed to clean up properly. + +Specifically, calling `setState()` in an unmounted component means that your app is still holding a reference to the component after the component has been unmounted - which often indicates a memory leak. + +**Example:** + +```js +/** + * setState() in unmounted component + */ +import React, { Component } from "react"; +import axios from "axios"; + +export default class App extends Component { + _isMounted = false; // flag to check Mounted + + constructor(props) { + super(props); + + this.state = { + news: [] + }; + } + + componentDidMount() { + this._isMounted = true; + + axios + .get("https://hn.algolia.com/api/v1/search?query=react") + .then((result) => { + if (this._isMounted) { + this.setState({ + news: result.data.hits + }); + } + }); + } + + componentWillUnmount() { + this._isMounted = false; + } + + render() { + return ( +
    + {this.state.news.map((topic) => ( +
  • {topic.title}
  • + ))} +
+ ); + } +} +``` + +Here, even though the component got unmounted and the request resolves eventually, the flag in component will prevent to set the state of the React component after it got unmounted. + + + +### Lifting State Up? + +The common approach to share **state** between two components is to move the state to common parent of the two components. This approach is called as lifting state up in React.js. With the shared state, changes in state reflect in relevant components simultaneously. + +**Example:** + +The App component containing PlayerContent and PlayerDetails component. PlayerContent shows the player name buttons. PlayerDetails shows the details of the in one line. + +The app component contains the state for both the component. The selected player is shown once we click on the one of the player button. + +```js +/** + * Lifting State Up + */ +import React from "react"; +import PlayerContent from "./PlayerContent"; +import PlayerDetails from "./PlayerDetails"; + +export default class App extends React.Component { + constructor(props) { + super(props); + this.state = { selectedPlayer: [0, 0], playerName: "" }; + this.updateSelectedPlayer = this.updateSelectedPlayer.bind(this); + } + updateSelectedPlayer(id, name) { + const arr = [0, 0, 0, 0]; + arr[id] = 1; + this.setState({ + playerName: name, + selectedPlayer: arr + }); + } + render() { + return ( +
+ + + +
+ ); + } +} +``` + +```js +/** + * PlayerContent + */ +import React, { Component } from "react"; + +export default class PlayerContent extends Component { + render() { + return ( + + ); + } +} +``` + +```js +/** + * PlayerDetails + */ +import React, { Component } from "react"; + +export default class PlayerDetails extends Component { + render() { + return

{this.props.name}

; + } +} +``` + + + +### "Children" in React? + +In React, **children** refer to the generic box whose contents are **unknown** until they\'re passed from the parent component. Children allows to pass components as data to other components, just like any other prop you use. + +The special thing about children is that React provides support through its `ReactElement API` and `JSX`. XML children translate perfectly to React children! + +**Example:** + +```js +/** + * Children in React + */ +const Picture = (props) => { + return ( +
+ + {props.children} +
+ ) +} +``` + +This component contains an `` that is receiving some props and then it is displaying `{props.children}`. +Whenever this component is invoked `{props.children}` will also be displayed and this is just a reference to what is between the opening and closing tags of the component. + +```js +/** + * App.js + */ + +render () { + return ( +
+ + {/** what is placed here is passed as props.children **/} + +
+ ) +} +``` + + +### Compound Components + +The Compound components are a pattern in which components are used together such that they share an implicit state that lets them communicate with each other in the background. + +Internally they are built to operate on a set of data that is passed in through children instead of props. Behind the scenes they make use of React\'s lower level API such as `React.children.map()`, and `React.cloneElement()`. Using these methods, the component is able to express itself in such a way that promotes patterns of composition and extensibility. + +**Example:** + +```js +function App() { + return ( + + + Actions + + + alert('Download')}>Download + alert('Copy')}>Create a Copy + alert('Delete')}>Delete + + + ) +} +``` + +In this example, the `` establishes some shared implicit state. The ``, ``, and `` components each access and/or manipulate that state, and it\'s all done implicitly. This allows you to have the expressive API you're looking for. + ---