Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
July 18, 2020 07:12 am GMT

React : Painting a Mental Model

Whether youve been working with React for years or are just starting, having a useful mental model is, in my opinion, the fastest way to feel confident working with it.
By having a good mental model you can intuitively understand complex problems and device solutions much faster than if you had to find a solution with a step-by-step process.

Disclaimer: This article is written by a beginner trying to comb through new concepts he just learned. Also available on my Blog where I explain the mental models that helped me solve problems and tame complexity.

why Are Mental Models Important?

When I started building websites,I had a hard time understanding how it all worked. Building blog sites with WordPress was easy, but I had no idea about hosting, servers, DNS, certificates, and much more.

As I read articles and tried stuff out, I started to grasp the system, to get glimpses into how it all worked, until eventually it clicked and I felt comfortable working with it. My mind had built a mental model around this system that I could use to work with it.

If someone had explained it by transferred their mental model to me, I wouldve understood it much faster. Here Ill explain (and show) the mental models I use with React. It will help you understand React better and make you a better developer.

React Mental Models

React helps us build complex, interactive UIs more easily than ever before. It also encourages us to write code in a certain way, guiding us to create apps that are simpler to navigate and understand.

An abstract model inside a mind looking at the React logo
React itself is a mental model with a simple idea at its core: encapsulate portions of your app that rely on similar logic and UI and React will make sure that portion is always up kept up to date.

Whether youve been working with React for years or are just starting, having a clear mental model is the best way to feel confident working with it. So for me to transfer my mental models to you Ill start from first-principles and build on top of them.

Its Functions All The Way Down

Lets start by modeling the basic building blocks of JavaScript and React: functions.

A React component is just a function

Components containing other components are functions calling other functions
Props are the functions arguments
This is hidden away by JSX, the markup language React uses. Strip away JSX and React is a bunch of functions calling one another. JSX is in itself an applied mental model that makes using React simpler and more intuitive.

Lets look at each part individually.

A Component Is A Function That Returns JSX

React is used with JSXJavaScript XMLa way to write what seems as HTML with all of JavaScripts power. JSX offers a great applied mental model for using nested functions in a way that feels intuitive.

Lets ignore class components and focus on the far more common functional components. A functional component is a function that behaves exactly like any other JavaScript function. React components always return JSX which is then executed and turned into HTML.

This is what simple JSX looks like:

const Li = props => <li {...props}>{props.children}</li>;export const RickRoll = () => (  <div>    <div className='wrapper'>      <ul>        <Li color={'red'}>Never give you up</Li>      </ul>    </div>  </div>);

Which compiled into pure JavaScript by Babel:

const Li = props => React.createElement('li', props, props.children);export const RickRoll = () =>  React.createElement(    'div',    null,    React.createElement(      'div',      {        className: 'wrapper',      },      React.createElement(        'ul',        null,        React.createElement(          Li,          {            color: 'red',          },          'Never give you up',        ),      ),    ),  );

If you find this code difficult to follow youre not alone, and you will understand why the React team decided to use JSX instead.

Now, notice how each component is a function calling another function, and each new component is the third argument for the React.createElement function. Whenever you write a component, its useful to keep in mind that its a normal JavaScript function.

An important feature of React is that a component can have many children but only one parent. I found this a confusing until I realized its the same logic HTML has, where each element must be inside other elements, and can have many children. You can notice this in the code above, where theres only one parent div containing all the children.

Components Props Are The Same As A Functions Arguments

When using a function we can use arguments to share information with that function. For React components we call these arguments props (funny story, I didnt realize props is short for properties for a long time).

Under the hood, props behave exactly like function arguments, the differences are that we interact with them through the nicer interface of JSX, and that React gives extra functionality to props such as children.

Creating A Mental Model Around Functions

Using this knowledge lets craft a mental model to intuitively understand functions!

When I think about a function I imagine it as a box, and that box will do something whenever its called. It could return a value or not:

function sum(a, b) {  return a + b;}console.log(sum(10, 20)); // 30function logSum(a, b) {  console.log(a + b); // 30}

Since a component is a fancy function, that makes a component a box as well, with props as the ingredients the box needs to create the output.

When a component is executed it will run whatever logic it has, if any, and evaluate its JSX. Any tags will become HTML and any component will be executed, and the process is repeated until reaching the last component in the chain of children.

Since a component can have many children but only one parent I imagine multiple components as a set of boxes, one inside another. Each box must be contained within a bigger box and can have many smaller boxes inside.

But the mental model of a box representing a component is not complete without understanding how it can interact with other boxes.

How To Think About Closures

Closures are a core concept in JavaScript. They enable complex functionality in the language, theyre super important to understand to have a good mental model around React.

Theyre also one of the features newcomers struggle with the most, so instead of explaining the technicalities Ill demonstrate the mental model I have around closures.

The basic description of a closure is that its a function. I imagine it as a box that keeps whats inside of it from spilling out, while allowing the things outside of it from entering, like a semi-permeable box. But spilling out where?

While the closure itself is a box, any closure will be inside bigger boxes, with the outermost box being the Window object.

A box describing a mental model of a javascript closure, showing Window, scripts and React apps
The window object encapsulates everything else

But What Is A Closure?

A closure is a feature of JavaScript functions. If youre using a function, youre using a closure.

As Ive mentioned, a function is a box and that makes a closure a box too. Considering that each function can contain many others inside of it, then the closure is the ability of a function to use the information outside of it, while keeping the information it has inside from spilling out, or being used by the outer function.

Speaking in terms of my mental model: I imagine the functions as boxes within boxes, and each smaller box can see the information of the outer box, or parent, but the big box cannot see the smaller ones information. Thats as simple and accurate an explanation of closures as I can make.

Closures are important because they can be exploited to create some powerful mechanics and React takes full advantage of this.

Closures In React

Each React component is also a closure. Within components, you can only pass props down from parent to child and the parent cannot see whats inside the child, this is an intended feature to make our apps data flow simpler to trace. To find where data comes from, we usually need to go up the tree to find which parent is sending it down.

A great example of closures in React is updating a parents state through a child component. Youve probably done this without realizing you were messing around with closures.

To start, we know the parent cant access the childs information directly, but the child can access the parents. So we send down that info from parent to child through props. In this case, the information takes the shape of a function that updates the parents state.

const Parent = () => {  const [count, setCount] = useState(0);  return (    <div>      The count is {count}      <div>        <ChildButtons onClick={setCount} count={count} />      </div>    </div>  );};const ChildButtons = props => (  <div>    <button onClick={() => props.onClick(props.count + 1)}>      Increase count    </button>    <button onClick={() => props.onClick(props.count - 1)}>      Decrease count    </button>  </div>);

When an onClick happens in a button, that will execute the function received from props props.onClick, and update the value using props.count.

The insight here lies in the way were updating a parents state through a child, in this case, the props.onClick function. The reason this works is that the function was declared within the Parent components scope, within its closure, so it will have access to the parents information. Once that function is called in a child, it still lives in the same closure.

This can be hard to grasp, so the way I imagine it is as a tunnel between closures. Each has its own scope, but we can create a one-way communication tunnel that connects both.

Once we understand how closures affect our components, we can take the next big step: React state.

Fitting Reacts State Into Our Mental Model

Reacts philosophy is simple: it handles when and how to render elements, and developers control what to render. State is our tool to decide that what.

When state changes, its component renders and therefore re-executes all the code within. We do this to show new, updated information to the user.

In my mental model state is like a special property inside the box. Its independent of everything else that happens within it. It will get a default value on the first render and always be up to date with the latest value.

Each variable and function is created on every render, which means their values are also brand new. Even if a variables value never changes, it is recalculated and reassigned every time. Thats not the case with state, it only changes when theres a request for it to change via a set state event.

State follows a simple rule: Whenever it changes it will re-rendered the component and its children. Props follow the same logic, if a prop changes, the component will re-render, however, we can control state by modifying it, props are more static and usually change as a reaction to a state change.

The Rendering Mental Model: Understanding Reacts Magic

I consider rendering to be Reacts most confusing part because a lot of things happen during rendering that sometimes isnt obvious by looking at the code. Thats why having a clear mental model helps.

The way I imagine rendering with my imaginary boxes is two-fold: the first render brings the box into existence, thats when the state is initialized. The second part is when it re-renders, thats the box being recycled, most of it is brand new but some important elements of it remain namely state.

On every render, everything inside a component is created, including variables and functions, thats why we can have variables storing a calculations results, since they will be recalculated on every render. Its also why functions are not reliable as values, due to their reference (the functions value, per se) being different every render.

const Thumbnail = props => (  <div>    {props.withIcon && <AmazingIcon />}    <img src={props.imgUrl} alt={props.alt} />  </div>);

The above will give a different result depending on the props the component receives. The reason React must re-render on every prop change is that it wants to keep the user up to date with the latest information.

However, the state doesnt change on re-renders, its value is maintained. Thats why the box is recycled instead of created brand new every time. Internally, React is keeping track of each box and making sure its state is always consistent. Thats how React knows when to update a component.

By imagining a box being recycled I can understand whats going on inside of it. For simple components, its easy to grasp, but the more complex a component becomes, the more props it receives, the more state it maintains, the more useful a clear mental model becomes.

A Complete React Mental Model: Putting It All Together.

Now that Ive explained all the different parts of the puzzle separately, lets put it all together. Heres the complete mental model I use for React components, directly translated from how I imagine them into words.

I imagine a React component as a box that contains all of its information within its walls, including its children, which are more boxes.

And like a box in the real world, it can have other boxes inside of it and these boxes can, in turn, contain more boxes. That way each box/component must have a single parent, and a parent can have many children.

The boxes are semi-permeable, meaning they never leak anything to the outside but can use information from the outside as if it belonged to them. I imagine like this to represent how closures work in JavaScript.

In React the way to share information between components is called props, the same idea applies to function and then its called arguments, they both work in the same way but with a different syntax.

Within components, information can only travel down from parents to children. In other words, children can access their parents data and state, but not the other way around, and the way we share that information is through props.

I imagine this directional sharing of information as boxes within boxes. With the inner-most box being able to absorb the parents data.

React Mental model of data sharing between components visualized as information flowing downward as Data is shared from parent to child.
The box must first be created though, and this happens on render, where the default value is given to state and just like with functions, all the code within the component is executed. In my mental model, this is equivalent to the box being created.

Subsequent renders, or re-renders, execute all the code in the component again, recalculating variables, recreating functions, and so on. Everything except for state is brand new on each render. States value is maintained across renders is updated only through a set method.

In my mental model, I see re-rendering as recycling the box since most of it is recreated, but its still the same box due to React keeping track of the components state.

When a box is recycled all the boxes within it, its children, are also recycled. This can happen because the components state was modified or a prop changed.

Remember that a state or prop changing means the information the user sees is outdated, and React always wants to keep the UI updated so it re-renders the component that must show the new data.

Conclusion

By using these mental models I feel confident when working with React. They help me visualize what can be a maze of code into a comprehensive mental map. It also demystifies React and brings it to a level Im much more comfortable with.

React is not that complex once you start understanding the core principles behind it and create some ways to imagine how your code works.

I hope this article was useful to you and it was as enjoyable to read as it was to write! I realized that I understand React intuitively and putting that understanding into words was challenging.


Original Link: https://dev.to/carter/react-painting-a-mental-model-1hd8

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To