0% found this document useful (0 votes)
13 views27 pages

React Issue Tracker Component Guide

The document outlines the development of a React-based Issue Tracker application, detailing the requirements for viewing, adding, editing, and deleting issues. It explains the use of React components, state management, and event handling, emphasizing component composition and the distinction between state and props. Additionally, it covers best practices for designing components, lifting state up, and utilizing stateless components for efficient data handling.

Uploaded by

anamijames03
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
13 views27 pages

React Issue Tracker Component Guide

The document outlines the development of a React-based Issue Tracker application, detailing the requirements for viewing, adding, editing, and deleting issues. It explains the use of React components, state management, and event handling, emphasizing component composition and the distinction between state and props. Additionally, it covers best practices for designing components, lifting state up, and utilizing stateless components for efficient data handling.

Uploaded by

anamijames03
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

REACT COMPONENTS

React components can be composed using other components and basic HTML elements. They
can respond to user input, change state, interact with other components.

Issue Tracker

• In the case of the Issue Tracker, we’ll only deal with a single object or record.

Requirement list for the Issue Tracker application

• The user should be able to view a list of issues, with an ability to filter the list by various
parameters.

• The user should be able to add new issues, by supplying the initial values of the issue’s
fields.

• The user should be able to edit and update an issue by changing its field values.

• The user should be able delete an issue.

An issue should have following attributes:

➢ A title that summarizes the issue (freeform long text)

➢ An owner to whom the issue is assigned (freeform short text)

➢ A status indicator (a list of possible status values)

➢ Creation date (a date, automatically assigned)

➢ Effort required to address the issue (number of days, a number)

➢ Estimated completion date or due date (a date, optional)

React Classes

• React classes are used to create real components. These classes can then be reused
within other components, handle events, etc.

• React classes are created by extending [Link], the base class from which all
custom classes must be derived.

• render() method is what React calls when it needs to display the component in the UI,
otherwise the component will have no screen presence.
• The render() function is supposed to return an element

Below are the steps to demonstrate React Classes:

• Hello World from a simple element to use a React class called HelloWorld, extended
from [Link]:

• Within this class, a render() method is needed, which should return an element.

• Move all the code for message construction to within the render() function

• The JSX element is now returned from the render() method of the component class
called Hello World. An instance of a div element was created using JSX of the form,
an instance of the HelloWorld class can be created like this

• This element can be used in place of the element to render inside the node called
contents
• [Link]: A Simple React Class and Instance

Composing Components

• Component composition is one of the most powerful features of React.

• Here, the UI can be split into smaller independent pieces so that each piece can be coded
and reasoned in isolation, making it easier to build and understand a complex UI.

• A component takes inputs (called properties) and its output is the rendered UI of the
component.

• Here are a few things to remember when composing components

1. Larger components should be split into fine-grained components when there is a


logical separation possible between the fine-grained components.

2. When there is an opportunity for reuse, components can be built which take in
different inputs from different callers.

3. React’s philosophy prefers component composition in preference to inheritance.

4. Keep coupling between components to a minimum


Sample to demonstrate Composing Components

• Main page of the application to show a list of issues, with an ability to filter the issues
and create a new issue

• It will have three parts:

1. A filter to select which issues to display

2. The list of issues

3. An entry form for adding an issue

• Define three placeholder classes—IssueFilter, IssueTable, and IssueAdd—with just a


placeholder text within a in each.

• The IssueFilter component will look like this:

• The other two classes—IssueTable and IssueAdd—will be similar, with a different


placeholder message each
• Let’s use a Fragment component like this in the IssueList’s render() method

• Finally, instead of instantiating a HelloWorld class, let’s instantiate the IssueList class,
which we will place under the contents div.

• Below shows the new contents of the [Link] file with all the component classes
Passing Data Using Children

• Passing data to other components, using the contents of the HTML-like node of the
component. This can be accessed using a special field of [Link] called
[Link].

• React lets the parent component access the children element using [Link]
and lets the parent component determine where it needs to be displayed.

• This works great when one needs to wrap other components within a parent component.

• For example, a wrapper that adds a border and a padding can be defined like this:

• Then, during the rendering, any component could be wrapped with a padded border like
this:

• Now, within the render() method of IssueRow, instead of referring to


[Link].issue_title, it will need to be referred to as [Link], like this:

• [Link]: Using Children Instead of Props


Dynamic Composition

• Here instead of using hard-coded set of components we use a programmatically


generated set of components.

• To demonstrate dynamic composition, we could use in-memory array, declared


globally at the beginning of the file [Link]
• Modify the IssueTable class to use this array of issues rather than the hard-coded list.

• The render() method, iterates over the array of issues and generate an array of
IssueRows from it.

• The map() method of Array can map an issue object to an IssueRow instance.

• Create a variable in the render() method and use that in the JSX

• we can replace the two hard-coded issue components inside IssueTable with this
variable within the <tbody> element

• Create a class for the table, name it table-bordered, and use CSS to style the table and
each table-cell instead.

• Identify each instance of IssueRow with an attribute called key. We can use the ID of
the issue as the key
• The final IssueTable class with a dynamically generated set of IssueRow components
and the modified header is shown below

• [Link]: New IssueRow Class Using Issue Object Property


React State

• To make components that respond to user input and other events, React uses a data
structure called state in the component.

• The state essentially holds the data, something that can change.

• This state needs to be used in the render() method to build the view.

• When data or the state changes, React automatically rerenders the view to show the
new changed data.

Initial State

• The state of a component is captured in a variable called [Link] in the component’s


classs, which should be an object consisting of one or more key-value pairs, where each
key is a state variable name and the value is the current value of that variable.

• It is useful to store in the state anything that affects the rendered view and can change
due to any event.

• To demonstrate this, we could use an array of issues as the one and only state of the
component and use that array to construct the table of issues.

• Rename global array of issues array to initialIssues

• Setting the initial state needs to be done in the constructor of the component.

• This can be done by simply assigning the variable [Link] to the set of state variables
and their values.
• The set of all changes to use the state to render the view of IssueTable is shown below

Async State Initialization

• This has to be fetched via an API call

• Let’s add a method to the IssueTable class that asynchronously returns an array of
issues.

• React provides many methods called lifecycle methods to accommodate this and other
situations where something needs to be done depending on the stage, or changes in the
status of the component

1. componentDidMount():
➢ This method is called as soon as the component’s representation has been converted
and inserted into the DOM. A setState() can be called within this method.
2. componentDidUpdate():
➢ This method is invoked immediately after an update occurs. [Link]() can be
called within this method.
➢ The method is also supplied the previous props and previous state as arguments, so
that the function has a chance to check the differences between the previous props
and state and the current props and state before taking an action.

3. componentWillUnmount():
➢ This method is useful for cleanup such as cancelling timers and pending network
requests.

4. shouldComponentUpdate():
➢ This method can be used to optimize and prevent a rerender in case there is a change
in the props or state that really doesn’t affect the output or the view.
➢ The best place to initiate the loading of data in this case is the
componentDidMount() method.
➢ The complete set of changes in the IssueTable class is shown below
Updating State

• There are libraries called immutability helpers, such as [Link] can be used to
construct the new state object. When a property of the object is modified, the library
creates a copy optimally.

• The simple way to make a copy of an array is using the slice() method. So will create a
copy of the issues array like this:

• let’s just add a timer, on the expiry of which, a hard-coded sample issue will be
appended to the list of issues. Let’s first declare this hard-coded sample issue object
globally, right after the global initialIssues:

• Let’s use this object in a call to createIssue(), after the expiry of a timer of two seconds,
in the constructor of IssueTable:

• The final set of changes for using a timer to append a sample issue to the list of issues
is shown below
Lifting State Up

• By lifting the state up on level to IssueList, information can be propagated down to


IssueAdd as well as to IssueTable.

• The way around this is to have the common parent contain the state and all the methods
that deal with this state.

• Let’s start by moving the state to IssueList and the methods to load the initial state.

• The constructor of IssueTable had both the state initialization as well as the timer, of
which only the state initialization needs to move.

• The other methods that deal with the state are componentDidMount(), loadData(), and
createIssue().

• Let’s move these also to the IssueList class:

• Pass the array of issues from the state within IssueList to IssueTable via props:
• Within IssueTable, instead of referring to the state variable issues, we’ll need to get the
same data from props:

• Pass the method itself as part of the props to IssueAdd from IssueList, so that it can be
called from IssueAdd.

• let’s create a constructor in IssueAdd and move the timer set up with a minor change to
use the createIssue callback passed in via props like this:

• Example 1: [Link], IssueAdd: New IssueAdd Class


• Example 2: [Link]: New IssueTable Class

• Example 3: [Link], IssueList: New IssueList Class


Event Handling

• To handle events such as onclick and onsubmit, the properties that we need to supply
to the elements are, simply, onClick and onSubmit.

• As in plain HTML and JavaScript, these properties take functions as values.

• We’ll create a class method called handleSubmit() to receive the submit event from the
form when the Add button is clicked.

• let’s rewrite the form declaration with a name and an onSubmit handler like this.

• In order to prevent the form from being submitted when the Add button is clicked, we
need to call the preventDefault() function on the event.

• To let this method have access to the object variables via this, we need to bind it to this
in the constructor:

• The new full code of the IssueAdd class, after these changes
Stateless Components

• components are written as functions rather than classes: a function that takes in props
and just renders based on it.

• It’s as if the component’s view is a pure function of its props, and it is stateless.
• If the rendering depends on the props alone, the function can be written with one
argument as the props, which can be accessed within the function’s JSX body.

• Example 1: [Link], IssueRow as a Stateless Component


• Example 2: [Link], IssueTable as a Stateless Component
Designing Components

1. State vs. Props

• Both state and props hold model information, but they are different. The props are
immutable, whereas state is not.

• State variables are passed down to child components as props because the children don’t
maintain or modify them.

• Anything that can change due to an event anywhere in the component hierarchy qualifies
as being part of the state.

2. Component Hierarchy

• The component should be self-contained with minimal and logical interfaces to the
parent.

• Doing many things in a component should be probably be split into multiple


components, so that it follows the Single Responsibility principle.

• If you are passing in too many props to a component, it is an indication that either the
component needs to be split, or it need not exist: the parent itself could do the job.

Example:

• In the Issue Tracker, the issues array was represented by the IssueTable component,
and each issue was represented by the IssueRow component.

3. Communication

• Communication between components depends on the direction.

• Parents communicate to children via props; when state changes, the props automatically
change. Children communicate to parents via callbacks.
Example:

• The IssueAdd component had to insert a row in IssueTable. It was achieved by keeping
the state in the least common ancestor, IssueList. The addition was initiated by
IssueAdd and a new array element added in IssueList’s state via a callback. The result
was seen in IssueTable by passing the issues array down as props from IssueList.

4. Stateless Components

• In a well-designed application, most components would be stateless functions of their


properties.

• All states would be captured in a few components at the top of the hierarchy, from
where the props of all the descendants are derived.

• We did with the IssueList, where we kept the state. We converted all descendent
components to stateless components, relying only on props passed down the hierarchy
to render themselves. We kept the state in IssueList because that was the least common
component above all the descendants that depended on that state.

Passing Data Using Properties


• The easiest way to pass data to child components is using an attribute when instantiating
a component.

• Within the render() method of the child, the attribute’s value can be accessed via a
special object variable called props, which is available via the this accessor.

• Example: This is how the value of issue_title can be displayed within a cell in the
IssueRow component:

• Any JavaScript expression can be passed along, by using curly braces ({}) instead of
quotes, because the curly braces switches into the JavaScript world.

• Example: [Link]: IssueRow Component, Accessing Passed-in Properties


Here,

➢ Property being passed on to the built-in React component . It’s just that the style
property in the td component is interpreted and set as the HTML style attribute.

• React needs it to be specified as an object with a specific convention containing a series


of JavaScript key-value pairs. The keys are the same as the CSS style name, except that
instead of dashes (like border-collapse), they are camel cased (like borderCollapse).
The values are CSS style values, just as in CSS.

• Let’s give the rows a silver border of one pixel and some padding, say four pixels. The
style object that would encapsulate this specification would be as follows:

• This can be passed on to the IssueRow component using rowStyle={rowStyle} when


instantiating it. This, and the other variables, can be passed to IssueRow while
instantiating it like this:

• Example: [Link]: IssueTable Passing Data to IssueRow

You might also like