React Flashcards
Benefits of design patterns
Components are:
- reusable
- styles are extensible
- easy API - props
- loose coupling - can be moved around easily because not tightly coupled to other components.
What is tight coupling?
How tightly coupled one component is to another. If tightly coupled then it cannot be moved around easily.
Atomic design
1) Atoms are the smallest building blocks eg. buttons, input fields
2) Atoms come together to form molecules - for example an input field and button together.
3) Molecules and atoms can be combined to form organisms - a container component
4) Organisms are used on the page
HOC
It’s a function that takes a component, adds some additional functionality to it (lifecycle methods), or props to it, and returns a new enhanced component with these new props. Use withBlaBlaBla as convention. Similar to the purpose of custom hooks, but an outdated way of doing it.
Where can custom hooks be used?
In functional components
in other custom hooks
When is useEffect called?
After the component has been printed to the screen (rendered) and after the dependency array is initially set and after updates to values in the dependency array.
Why use Compound Component Pattern
Avoid prop-drilling / props overload: where props are sent to a component, just to send it to a child.
Example:
`
<table>
<Table.Row>
<Table.Column>
something
</Table.Column>
<Table.Column>
something two
</Table.Column>
</Table.Row>
</table>
`
In order to have this export syntax do the following as example
index.js
import {Column,Row,Table} from ‘./Table’;
Table.Row = Row;
Table.Column = Column;
export {Table};
Ducks pattern
This is specifically intended to be used with Redux, BUT, it can also be slightly tweaked for use with context.
All the action creators, and async actions (redux), the provider (context), the reducer (redux and context), the styles, the automated test should be housed in the component’s directory and only what is required outside of it, should be exposed via the index file.
Provider pattern
Create a context provider , which is a component that wraps other components, that are meant to consume the context (with useContext - createContext() result)
Best to use useReducer in the context provider, even though it isn’t necessary.
Render prop pattern - with child too
Similar to Vue slots, way of sending data back up is also possible.
Vue slots can be more than one though, with React this is not possible.
Compound Component Pattern, and two export approaches
Uses composition. Prevents props drilling or overload.
Export each component (the container and it’s children components) via the index file, OR
if you’d like the Table, Table.Row, Table.Col sort of approach, then just update the container component function (in JS functions are also objects):
import {Table,Row,Col} from ‘./Table’
Table.Row = Row;
Table.Col=Col;
export const Table;
Explain component composition
Use slots (in Vue) and children (in React) to create a wrapper component that can take children for customisation.
Example where Alert is the shell component:
<Alert>some custom content</Alert>
Error boundaries issue
React doesn’t have ErrorBoundary component built into it, but you can go to the react site to copy and paste an example component they give you. It’s class based. Better to use react-error-boundary package which abstracts this for you.
Basically handle errors thrown in components wrapped in the ErrorBoundary, by rendering an error or imperatively handling it as well.
Code splitting
Code splitting is where you only load imports (modules) into your application when they are needed, and not before-hand. This greatly improves the initial render.
This includes component, functions etc
The imports are called dynamic imports
example
onClick = {()=>{
import(‘./sum.js’).then(module=>{
module.sum(2+2); //for named ;
module.default() for default
})
}}
for components:
const Home = React.lazy(()=>import(‘./Home’)) // default export
//named exports
const About = React.lazy(()=>import(‘./About’).then(module)=>{
return {
default:module.About
}
})
Any lazily-loaded components need to be wrapped inside <Suspense fallback={<LoadingDisplay></LoadingDisplay>}></Suspense>
Container component pattern
Handle all state in the container component, as well as do Ajax requests, use hooks like context hooks, and handle all logic. Pass data down to children and hoist it back up via callbacks if necessary.
What does lifting state mean?
Lifting state from one component to the least common parent (like in container component pattern) is required when siblings share state. Colocation is the inverse.
What should not be used as a key for a list item?
An index, rather use id
What is a powerful custom hooks library
react-use
Explain refs?
Refs are references to DOM nodes/components - for custom components use forwardRefs()
All HTML elements have a ‘ref’ prop which is a callback that returns the reference to it.
Two ways of storing the ref:
`
const textRef = useRef();
return <input
ref={textRef}
type={‘text’}
/>
OR
<input
style={{ backgroundColor: ‘green’, height: ‘50px’ }}
ref={ref=>textRef.current = ref}
type={‘text’}
/>
The ref can then be used to manipulate the DOM element, for example textRef.current.focus() or textRef.current.blur();
`
For custom components you can use useImperativeHandle with the ref.
Explain useRef
This is a hook built into React
It doesn’t cause a re-render when it’s data is updated
The data stored within it is kept during re-render
Best not to mutate it, if current
holds an object as a value.
Reassign a value to it and access it via variableName.current
`
const someVar = useRef(initial value)
someVar.current=’new value’
// access it
someVar.current
`
State hoisting
Hoist the state of a component, via a callback that you send in as a prop, which is invoked in the child, with it’s state.
useState
The state updater returned by useState can be envoked with a new value, or with a function that is envoked by react and returns the previous state. Return the new state that it should become.
How to make useEffect not execute on render.
Using useRef.
`
const isMounted = useRef(false)
useEffect(()=>{
if(isMounted.current){
//do something
}
isMounted.current = true;
},[])
`
Explain forwardRef
Use it to implement a ref
prop on a custom component.
Send ref in to component
const someRef = useRef();
<MyComponent ref={someRef} />
const forwardRef((props,ref)=>(
<div ref={ref}></div>
));
How to create uncontrolled components for inputs
Add a ref to an input, using useRef, and then access ref.current
Use defaultValue to set initial value
Example:
const myName = useRef(‘’)
<input ref={myName} defaultValue=’Whatever’/>
//now
myName.current.value now contains the name value
useImperativeHandle
With this hook, you can manipulate a ref. Basically you can add methods or values onto a ref, by returning an object literal from the callback
useImperativeHandle(ref,()=>{
return {
one(){},
two:10,
}
},[])
A real-world example would be where you want to send down a singleref
to a custom component, but you want to use it to focus on more than one element, ie, normally more than one ref would need to be sent down without useImperativeHandle
const ref = useRef();
ref.current.one()
ref.current.two()
<CustomComponent ref={ref}/>
export const CustomComponent = forwardRef((props,ref)=>{
const ref1 = useRef();
const ref2= useRef();
useImperativeHandle(ref,()=>{
return {
one(){ref1.current.focus()},
two(){ref2.current.focus()}
}
},[])
return (
<>
<input></input>
<input></input>
</>
)
})
useId
Creates a unique HTML id to use in your mark-up. Every time you refresh the screen, if the DOM is the same, react generates the same value for this hook. This makes server side rendering and client side hydration un-problematic.
const id = useId()
useDeferredValue
This tells React to only update this value when React isn’t busy with other rendering/calculations etc. Tell React that this is low priority and doesn’t need to be updated instantaneously like useState() variables.
useTransition
This hook tells React to deprioritize code blocks that do state updates.
Generally state updates are chunked together for re-rendering, in order to minimise the amount of re-rendering.
By using useTransition, we can tell React that some state updates, and therefore re-rendering should only be done when React is not too busy.
const [name,setName] = useState(‘’);
const [surname,setSurname] = useState(‘’);
const [isPending,startTransition] = useTransition();
startTransition(()=>{
setSurname(‘blablabla’);
})
useLayoutEffect
Runs just before the component is printed to the screen, but after DOM has been calculated, with it’s measurements etc. Any manipulation pertaining to the DOM should be done in this hook and NOT useEffect
useDebugValue
For debugging - logs to dev tools. Only works in custom hooks, not in components.
useEffect cleanup
This is the function returned from the useEffect hook. It runs before the rest of the function body.
Important note is that the initial render also calls useEffect, but without first calling the cleanup function.
However, after the dependency array is set and updated, the cleanup function is called before the the rest of the function body.
It is also called when the component that uses the useEffect() is unmounted.
When is useImperativeHandle called?
Just like useEffect
Once the component is printed to the screen, when the dependency array is set, and after that when the dependencies are updated.
What is useEffect used for?
In order to perform side effects. If a side effect within the hook needs to be cleared/stopped, then return a function from it with this code.
This will execute when the component is unmounted, and also, just before the useEffect function body is executed again, unless it’s the initial render.
Without dependency array, it executes with every render/re-render
With empty array, it’s similar to componentDidMount(); It renders just after initial render, and when the dependency (empty) is set.
What is lazy loading
Only loading modules when they are required, like code splitting where React.lazy loads components only when required. React.Suspense is required for rendering though.
Suspense
It allows you to:
- Wait for ajax request to complete before rendering component wrapped in suspense. Fallback allows display of loading component during request
- with lazily loaded components
What are the rules around dependency arrays?
Never use an object OR array that is not memoized, or unmemoised function as an item in the list.
Reason being that arrays and objects are recreated with every render because even if the value is the same, it refers to a different item in the heap. useMemo counters this.
How do you set up redux in react app
Redux for framework agnostic functionality
Redux-toolkit or react-redux for react bindings and hooks etc.
Colocation
Things that work together, belong together. Container component pattern is example of this.