The Art of State: State Management in React Application, Part 2
Source: Heise.de added 18th Dec 2020A small blog application is used to illustrate the concepts and libraries shown in this article. The sample code to try out and understand how it works is on GitHub.
The post-editor (Fig. 1)
Managing and distributing status is a major challenge in large applications: How does it get to the Make the application that need the particular state? The standard way in React is to hand down properties: A component located higher up maintains the state. Via properties on the components, the status is explicitly passed on in whole or in part in the hierarchy to the point at which it is used. This applies not only to data, but also to functions that can trigger the change in status.
In the blog application from the first article, the Filter settings kept in a master component. The display and the associated interaction options of the filter are implemented in a sub-component. Therefore, the main component not only passes the current filter settings of the users to the sub-component, it also transfers the callback function onFilterByLikes . The subcomponent calls this function when users have changed the filter.
The global status is maintained in a supercomponent, which is passed through all levels up to the component using it together with callback functions (Fig. 2).
The main component then sets the new filter settings in their state (with useState or useReducer ). As a result of the status change, React then renders both the upper and the subcomponent, the latter now receives the updated filter settings and can display them.
However, this explicit passing on of status is triggered some places to its limits: for example, when the state has to be passed on over many levels that may not be interested in the information at all. For example, a theme could be set globally. However, this information tends to be only relevant for components at the lowest hierarchical level, as these require the theme information for correct display. This can be components from a component library, for example. All components in between must accept the theme property and pass it on, even if they have nothing to do with it (technically).
This approach also assumes that all components know their sub-components within the hierarchy at development time and be able to pass on the theme property. But that doesn’t always have to be the case. Forms serve as an example. The PostEditor component from the first article contains two input fields, the Users can fill out. In a realistic application, these two fields would be validated when editing the form (for example: The title may only be a maximum of 120 characters long and the content must not be empty). In addition, it must be recorded whether a field was visited at all, so that the validations are carried out for the first time after the user had even accessed a field. The result of the validation must then be managed for each field. These requirements can become arbitrarily complex, so that developers could build a form component that takes care of the validation at a central point.
For the individual elements of the form ( input , select …) own components are also built that are to communicate with the form object by triggering events ( “Entry has changed”, “Field was visited”) and receive data (text entered in the field, validation result). A corresponding form could look like this:
function PostEditor (props) {return ( Add Post ); } The exact functionality of the Form – component is irrelevant for this example. What is interesting, however, is that the components below it have to communicate with it, without the form component knowing its individual children. The explicit passing on of properties is difficult at this point because the form component only receives the “finished” children.
The React Context for the global state In such cases the React Context can be used. It makes any object available across component boundaries. The context consists of a provider component that is integrated in the component hierarchy of the application. All underlying components can then be accessed with the useContext hook on the Access values from the context. As soon as the values change, React renders the consumer components again so that they can display the updated data.
A context is created with the function React.createContext generated. Among other things, this function returns a consumer component. The provider component is used in its own technical component to make the object available, for example as follows:
const FormContext = React.createContext (); function form (props) {const = React.useState ({…}); // omitted: The actual logic and function of the form // The context should consist of an object, the // keys of which are the names of the form elements. // The associated values hold the information for a concrete // field (e.g. content, error message, etc.). // The context also contains a function for // changing the field values return { props.children} ; } All components below the Form – Components can now be used with useContext Get access to the state of the form without the form component having to know it. The context can also contain callback functions with which a consuming component can inform the provider component about events. The provider component for its part can then update its state and context, whereupon the consuming components are re-rendered. The procedure basically corresponds to the transmission of status and callback functions described above, only that the context status and functions do not have to be explicitly passed on via every layer in the component hierarchy.
With the React Context, a component can directly access the global data of a consumer component (Fig. 3).
For example, a component within the shape could have something like this interact with the context, on the one hand to display a value from it and to call a callback function to change it:
function TextField ({name}) {// select context. // Changing the context renders the TextField again const formState = React.useContext (FormContext); // use context const fieldValue = formState [name] ?. value || “”; const onChange = e => formState.onFieldChange (name, e.target.value); return } When using the form – or TextField -Component does not change anything, the code for the PostEditor Component would work now. The context can be used at every level of the application; it only ever affects the components that are below the provider component in the hierarchy. It can therefore be used for a completely global status (theme) as well as for a “partially global” status such as forms or individual areas of the application. For performance reasons, it is recommended to only use the context where the managed state is not changed frequently and at the same time quickly, or where not many components are affected by the change in the context.
brands: Built CODE New other media: Heise.de
Related posts
Notice: Undefined variable: all_related in /var/www/vhosts/rondea.com/httpdocs/wp-content/themes/rondea-2-0/single-article.php on line 88
Notice: Undefined variable: all_related in /var/www/vhosts/rondea.com/httpdocs/wp-content/themes/rondea-2-0/single-article.php on line 88
Related Products
Notice: Undefined variable: all_related in /var/www/vhosts/rondea.com/httpdocs/wp-content/themes/rondea-2-0/single-article.php on line 91
Warning: Invalid argument supplied for foreach() in /var/www/vhosts/rondea.com/httpdocs/wp-content/themes/rondea-2-0/single-article.php on line 91