React Module-2: JSX, Props,React Element, Unit Testing,TDD,Performance Optimization and so on.
This is the second module of React learning.Let’s explore something new —
1) JSX:
By using JSX we are able to write concise HTML/XML-like structures (e.g., DOM like tree structures) in the same file as we write JavaScript code, then Babel will transform these expressions into actual JavaScript code. Unlike the past, instead of putting JavaScript into HTML, JSX allows us to put HTML into JavaScript.
Example:
JSX Code:
<MyButton color="blue" shadowSize={2}>Click Me</MyButton>
Babel transform:
React.createElement(MyButton,{color: 'blue', shadowSize: 2},'Click Me')
Specifying The React Element Type:
The first part of a JSX tag determines the type of the React element.
i) React Must Be in Scope
function WarningButton() {// return React.createElement(CustomButton, {color: ‘red’}, null);return <CustomButton color=”red” />;
ii) Using Dot Notation for JSX Type
import React from 'react';const MyComponents = {DatePicker: function DatePicker(props) {return <div>Imagine a {props.color} datepicker here.</div>;}}function BlueDatePicker() {return <MyComponents.DatePicker color="blue" />;}
iii) User-Defined Components Must Be Capitalized
function HelloWorld() {// Correct! React knows <Hello /> is a component because it’s capitalized.return <Hello toWhat=”World” />;}
iv) Choosing the Type at Runtime
function Story(props) {// Correct! JSX type can be a capitalized variable.const SpecificStory = components[props.storyType];return <SpecificStory story={props.story} />;}
2) Props in JSX
There are several different ways to specify props in JSX.
i) JavaScript Expressions as Props: We can pass any JavaScript expression as a prop, by surrounding it with {}
. For example, in this JSX:
<MyComponent foo = {1 + 2 + 3 + 4} />
ii) String Literals: It also can pass a string literal as a prop. These two JSX expressions are equivalent:
<MyComponent message="hello world" /><MyComponent message={'hello world'} />
iii) Props Default to “True”: If we pass no value for a prop, it defaults to true
. These two JSX expressions are equivalent:
<MyTextBox autocomplete /><MyTextBox autocomplete={true} />
iv) Spread Attributes
If already have props
as an object, and we want to pass it in JSX, we can use ...
as a “spread” operator to pass the whole props object. These two components are equivalent:
function App1() {return <Greeting firstName="Ben" lastName="Hector" />;}function App2() {const props = {firstName: 'Ben', lastName: 'Hector'};return <Greeting {...props} />;}
3) propTypes
React has some built-in typechecking abilities. To run typechecking on the props for a component, we can assign the special propTypes
property:
import PropTypes from 'prop-types';class Greeting extends React.Component {render() {return (<h1>Hello, {this.props.name}</h1>);}}Greeting.propTypes = {name: PropTypes.string};
PropTypes
exports a range of validators that can be used to make sure the data you receive is valid. In this example, we’re using PropTypes.string
. When an invalid value is provided for a prop, a warning will be shown in the JavaScript console. For performance reasons, propTypes
is only checked in development mode.
4) Default Prop Values
It can possible to define default values props
by assigning to the special defaultProps
property:
class Greeting extends React.Component {static defaultProps = {name: 'stranger'}render() {return (<div>Hello, {this.props.name}</div>)}}
The defaultProps
will be used to ensure that this.props.name
will have a value if it was not specified by the parent component. The propTypes
typechecking happens after defaultProps
are resolved, so typechecking will also apply to the defaultProps
.
5) Why Not Use try
/ catch
?
try
/ catch
only works for imperative code:
try {showButton();} catch (error) {// ...}
However, React components are declarative and specify what should be rendered:
<Button />
Error boundaries preserve the declarative nature of React, and behave as you would expect. For example, even if an error occurs in a componentDidUpdate
method caused by a setState
somewhere deep in the tree, it will still correctly propagate to the closest error boundary.
6) Unit Testing
Unit testing is a level of software testing where individual units/ components of a software are tested. The purpose is to validate that each unit of the software performs as designed.
7) Pros of Unit Testing
i) Unit testing increases confidence in changing/ maintaining code.
ii) Codes are more reusable.
iii) Development is faster.
iv) The cost of fixing a defect detected during unit testing is lesser in comparison to that of defects detected at higher level
v) Debugging is easy. When a test fails, only the latest changes need to be debugged.
vi) Codes are more reliable.
vii) Architecture improvements
8) Test-Driven Development
TDD is an approach to writing software where we write tests before writing application code. TDD helps us to develop a robust test suite to catch bugs, as well as guiding us to a more modular, flexible code.
9) How to perform TDD Test
Following steps define how to perform TDD test,
1. Add a test.
2. Run all tests and see if any new test fails.
3. Write some code.
4. Run tests and Refactor code.
5. Repeat.
10) Optimizing Performance:
Internally, React uses several clever techniques to minimize the number of costly DOM operations required to update the UI. While this will lead to a faster user interface without specifically optimizing for performance for many cases, there are ways where you can still speed up your React application.
i) Using Production Mode Flag in Webpack
ii) Use React.Fragments
to Avoid Additional HTML Element Wrappers
iii) Avoid Inline Function Definition in the Render Function.
iv) Avoid using Index as Key for map
v) Avoiding Props in Initial States
vi) Using Immutable Data Structures
vii) Function/Stateless Components and React.PureComponent and so on.
SO….enough for today.Happy learning.