A main element of my goals for the next year are to level up my technical knowledge both in terms of breadth and depth of particular topics. I thought a fun, achievable step towards that goal is to read one technical article a day and write a quick summary of what Iâve learned from it. So far I only had time for 4 articles this week, but Iâm aiming for 5 a week.
So here we are, the first in a series of weekly updates of short summaries of technical articles:
#1: Introducing the Single Element Pattern
Reliability: not needing to open the file and look at the code to understand how it works.
Rules for reliability: (really only works for primitive elements)
1. Render only one element
2. Never break the app:if missing proptypes, show as a warning instead of breaking rendering
3. Render all HTML attributes passed as props: instead of passing an object that renders html props (such as src
and alt
), make these the prototypes for the react component and then just render the propose the primitive as {âŚprops}
4. Always merge the styles passed as props: use object spread to merge style and className props
5. Add all the event handlers passed as props: always apply the event handler coming from the prop (your choice if it replaces the internal one or both are called)
Suggestions:
1. Avoid adding custom props
For example: if you have a rounded version of the same element, donât add a prop that is
rounded
, create a new element that isElementRounded
that rounds the edges
- Receive the underlying HTML element as a prop
Make your element more flexible - rendering a button as an anchor tag
#2 How JS works: an overview of the engine, the runtime, and the call stack
The JS engine:
- Googleâs V8 engine is used in Chrome and Node.js
- Consists of two main components: the memory heap (where memory allocation happens) and the call stack (wirer your stack frames are as your code executes
Runtime: web APIs provide things like setTimeout (not provided by the engine) and is supplied by the browser (eg. DOM, AJAX and setTimeout)
Call Stack: JS is single threaded so it has a single call stack (can only do one thing at a time)
- Call Stack is a data structure that recourses basically where in the program we are
- Stepping into a function puts at on the top of the stack and returning from a function we pop off the top of the stack
- Stack traces are the state of the call stack when the exception happened
- âblowing the stack" - when the number of function calls in the stack exceeds the actual size of the call stack (recursively calling a function with no termination)
Concurrency & the event loop:
What happens when you do a large resource intensive task that blocks the rest of the app from executing? browser may not be responsive for a long time + might prompt you to close the page
So how do we execute heavy code without blocking the UI? -> asynchronous callbacks
#3 React Fragments
JSX turns <div>
s and <MyComponent>
into React.createElement(
) calls so when there are multiple elements instead of a single one, it doesnât know what tag name to render with.
Solutions:
- wrap elements in a div
- use the render method to return an array of nodes (clunky + non-jsx-y)- the transpolar is putting together an array of React.createElement()
calls and affixing them to the parent element as children
render () {
return [
<p>hi</p>
<p>there!</p>
]
}
Best: React Fragment - behaves like the array method
render () {
return (
<React.Fragment>
<p>hi</p>
<p>there!</p>
</React.Fragment>
)
}
OR: more concise syntax
render () {
return (
<>
<p>hi</p>
<p>there!</p>
</>
)
}
#4 Understanding Reactâs setState()
setState() is the only legitimate way to update state after the initial state setup (donât update state directly because the component wonât re-render) - component is re-rendered with that state -> this process is called âreconciliationâ (how React updates the DOM)
React creates a new tree containing the reactive elements in the component and the updated state
This tree is used to figure out how the componentâs UI should change (compares the updated tree with the previous tree)
* React only updates the part of the component that have changed (makes it fast fast)
Canât call setState multiple times in a row (eg. trying to increment a value 3 times in a row)
handleIncrement = () => {
this.setState({ count: this.state.count + 1})
this.setState({ count: this.state.count + 1})
this.setState({ count: this.state.count + 1})
}
This is equivalent to:
Object.assign(
{},
{ count: this.state.count + 1 },
{ count: this.state.count + 1 },
{ count: this.state.count + 1 },
)
Object.assign is used to copy data from a source to a target object but if the data (being copied from the source to the target) all have the same keys, the last object wins.
What will work is using a function within setState() - React will queue the functions in the order they are made and update the entire state once it is done:
handleIncrement = () => {
this.setState((prevState) => ({ count: this.state.count + 1}))
this.setState((prevState) => ({ count: this.state.count + 1}))
this.setState((prevState) => ({ count: this.state.count + 1}))
}
Accessing previous state:
- canât always trust this.state right after setState() has been called - should be treated asynchronously
- Need to use an updater - like what is in the previous example (using a function that has prevState as an argument)