Working with Data in React: Properties & State
This article is part of a web development series from Microsoft. Thank you for supporting the partners who make SitePoint possible.
Managing data is essential to any application. Orchestrating the flow of data through the user interface (UI) of an application can be challenging. Often, today’s web applications have complex UIs such that modifying the data in one area of the UI can directly and indirectly affect other areas of the UI. Two-way data binding via Knockout.js and Angular.js are popular solutions to this problem.
For some applications (especially with a simple data flow), two-way binding can be a sufficient and quick solution. For more complex applications, two-way data binding can prove to be insufficient and a hindrance to effective UI design. React does not solve the larger problem of application data flow (although Flux does and will be thoroughly explained in a future article), but it does solve the problem of data flow within a single component.
Within the context of a single component, React solves both the problem of data flow, as well as updating the UI to reflect the results of the data flow. The second problem of UI updates is solved using a pattern named Reconciliation which involves innovative ideas such as a Virtual DOM. The next article will examine Reconciliation in detail. This article is focused on the first problem of data flow, and the kinds of data React uses within its components.
Kinds of Component Data
Data within React Components is stored as either properties or state.
Properties are the input values to the component. They are used when rendering the component and initializing state (discussed shortly). After instantiating the component, properties should be considered immutable. Property values can only be set when instantiating the component, then when the component is re-rendered in the DOM, React will compare between the old and new property values to determine what DOM updates are required.
Here is a demonstration of setting the property values and updating the DOM in consideration of updated property values.
State data can be changed by the component and is usually wired into the component’s event handlers. Typically, updating the state triggers React components re-render themselves. Before a component is initialized, its state must be initialized. The initialized values can include constant values, as well as, property values (as mentioned above).
In comparison with frameworks such as Angular.js, properties can be thought of as one-way bound data, and state as two-way bound data. This is not a perfect analogy since Angular.js uses one kind of data object which is used two different ways, and React is using two data objects, each with their specific usages.
When adding a CSS class name to a component, the property name
className must be used, rather than
class must be used. React requires this because ES2015 identifies the word
class as a reserved keyword and is used for defining objects. To avoid confusion with this keyword, the property name
className is used. If a property named
class is used, React will display a helpful console message informing the developer that the property name needs to be changed to
Observe the incorrect
class property name, and the helpful warning message displayed in the Microsoft Edge console window.
class property to
className, results in the warning message not being displayed.
When the property name is changed from
className the warning message does not appear. See below for the complete CodePen demonstration.
In addition to property names such as
className, React properties have other interesting aspects. For example, mutating component properties is an anti-pattern. Properties can be set when instantiating a component, but should not be mutated afterwards. This includes changing properties after instantiating the component, as well as after rendering it. Mutating values within a component are considered state, and tracked with the
state property rather than the
In the following code sample,
SomeComponent is instantiated with
createElement, and then the property values are manipulated afterwards.
props of the instantiated component could result in errors that would be hard to trace. Also, changing the properties does not trigger an update to the component, resulting in the component and the properties could be out of sync.
Instead, properties should be set as part of the component instantiation process, as shown below.
The component can then be re-rendered at which point React will perform its Reconciliation process to determine how the new property values affect the DOM. Then, the DOM is updated with the changes.
See the first CodePen demonstration at the top of this article for a demonstration of the DOM updates.
State represents data that is changed by a component, usually through interaction with the user. To facilitate this change, event handlers are registered for the appropriate DOM elements. When the events occur, the updated values are retrieved from the DOM, and notify the component of the new state. Before the component can utilize state, the state must be initialized via the
getInitialState function. Typically, the
getInitialState function initializes the state using static values, passed in properties, or another data store.
Continue reading %Working with Data in React: Properties & State%