React 2 Flashcards
ComponentDidMount and ComponentDidUpdate
useEffect
When does fetching data happen?
- fetching data from server occurs in ComponentDidMount and ComponentDidUpdate
- lifecycle method componentDidMount() initiates the fetch on first render and componentDidUpdate() refetches data when new props have been provided by a parent component or an internal state has been changed.
useEffect is componentDidMount and componentDidUpdate in one effect
* what happens if we want to send HTTP request only when it renders the first time on mount * we can specify in array argument a dependancy * or empty brackets says I have no dependancies so only run the first time = componentDidMount
useEffect
cleanup
- useEffect combines all the functionality of lifecycle hooks in one
- runs every render cycle (every time it rerenders, not in real DOM but in react/virtual DOM)
React performs the cleanup when the component unmounts. However, as we learned earlier, effects run for every render and not just once. This is why React also cleans up effects from the previous render before running the effects next time.
Memory leak occurs when programmers create a memory in heap and forget to delete it.
The consequences of memory leak is that it reduces the performance of the computer by reducing the amount of available memory. Eventually, in the worst case, too much of the available memory may become allocated and all or part of the system or device stops working correctly, the application fails, or the system slows down vastly .
- for cleanup of lifecycle hooks: componentWillUnmount
- in useEffect return with anonymous function
useEffect(() => { let mounted = true fetchAPI.then(() => { if (mounted) { setloading(false) } })
return function cleanup() { mounted = false } }, [])
Pure Component and React.memo()
To avoid unnecessary renders, thus reconciliation, we can use PureComponent (with class components) or React.memo() (with function components).
React.memo() does the same as PureComponent but it does not check for changes in state, only in props.
Very good article
https://medium.com/takeaway-tech/a-deep-dive-into-pure-component-and-react-memo-and-why-do-we-need-them-ae99dce6a33c
Two-way binding
benefits
When properties in the model get updated, so does the UI (View) When UI (View) elements get updated, the changes get propagated back to the model.
React doesn’t have a mechanism to allow the HTML to change the component. The HTML can only raise events that the component responds to. The typical example is by using onChange.
render() { return } handleChange(e) { this.setState({value: e.target.value}); } The value of the input is controlled entirely by the render function. The only way to update this value is from the component itself, which is done by attaching an onChange event to the input which sets this.state.value to with the React component method setState. The input does not have direct access to the components state, and so it cannot make changes. This is one-way binding. Angular works more like UI Data in contrast to React's Render(data)--->UI ?
Thanks to one-way bindings, data cannot flow in the opposite way (as would happen with two-way bindings, for example), and this has some key advantages: it’s less error prone, as you have more control over your data. it’s easier to debug, as you know what is coming from where.
The Pros and Cons of Redux and Context
Both Context and Redux are ways to manage state in a React app.
every context object comes with a Provider React component that allows consuming components to subscribe to context changes. It is the provider that allows the context to be consumed by other components.
The main benefit of using Context is that it is simpler to use and is a great way of passing state down to any level of a component tree without having to pass props down through traversal. Good for prop drilling.
The problem with context is simple: Everything that consumes a context re-renders everytime that context’s state changes. That means that if you’re consuming your context all over the place in your app, or worse, using one context for your entire app’s state, you’re causing a ton of re-renders all over the place!
But remember that context does NOT have to be global to the whole app, but can be applied to one part of your tree and you can (and probably should) have multiple logically separated contexts in your app.
Unless you separate your different states into separate Providers, the consumers of a provider will rerender if the context of a Provider changes. This can be very inefficient in a large app where the are many states you use as the context in a provider or if only a few states change that effect the renderings of other components.
https://stackoverflow.com/questions/53346462/react-multiple-contexts/53346541
Redux, on the other hand, attempts to make state mutations predictable by imposing certain restrictions on how and when updates can happen and are great for applications that have multiple states that will reach different components in a component tree. Redux comes in handy when you have an app that has a more complex state that is updating frequently. The main benefit is that if states have not changed they will not re-render.
Ultimately it depends on the size of your applications and what kinds of states your components will be using.
contextAPI vs redux
Context API: Resourceful and ideal for small applications where state changes are minimal
Redux: Perfect for larger applications where there are high-frequency state updates
Context also doesn’t give you anything like the Redux DevTools, the ability to trace your state updates, middleware to add centralized application logic, and other powerful capabilities that Redux enables.
Redux middleware provides a third-party extension point between dispatching an action, and the moment it reaches the reducer. People use Redux middleware for logging, crash reporting, talking to an asynchronous API, routing, and more.
Redux is much more powerful and provides a large number of features that the Context Api doesn’t provide, also as As @danAbramov mentioned
React Redux uses context internally but it doesn’t expose this fact in the public API. So you should feel much safer using context via React Redux than directly because if it changes, the burden of updating the code will be on React Redux and not you.
As we have now learned how both Redux and Context APIs work, we can compare them and understand their pros and cons.
Bundle size: The one thing we have to keep in mind is that Redux is a third-package library that is not a part of React, and hence we need to install the dependencies — mainly three of them (redux, react-redux, redux-thunk). Using Redux comes at a cost. Installing these dependencies increases our final bundle size. On the contrary, Context APIs are a part of React, so our bundle size remains the same.
Boilerplate code: With Redux, we need to have an exhaustive setup, we need to build a store, and we need to dispatch actions. We then need to connect our store with our components. Sometimes, this is a pain for a developer. There is a high chance that one might get lost in the codes and just wander aimlessly with no clue on how to fix anything. Basically, you need to have a hands-on approach to work with Redux. According to me, Context APIs involve less boilerplate codes. With the introduction of React 16.6, we don’t even need the consumer. With just one line of code, you can get access to your context.
Handle async code: In Context APIs, triggering an API (async codes) is relatively straightforward to use once you get the hang of it (especially when using Hooks). You also don’t need a package like redux-thunk to handle asynchronous actions.
What is HOC and it’s uses
https://www.smashingmagazine.com/2020/06/higher-order-components-react/
A higher-order component (HOC) is an advanced element for reusing logic in React components. Components take one or more components as arguments, and return a new upgraded component. Sounds familiar, right? They are similar to higher-order functions, which take some functions as an argument and produce a new function.
FACTS ABOUT HOCS
We don’t modify or mutate components. We create new ones.
A HOC is used to compose components for code reuse.
A HOC is a pure function. It has no side effects, returning only a new component.
Here are some examples of real-world HOCs you might have come across:
react-redux connect(mapStateToProps, mapDispatchToProps)(UserPage)
react-router withRouter(UserPage)
material-ui withStyles(styles)(UserPage)
The snippet below shows how a HOC is structured in React:
Show a loader while a component waits for data
//withdLoading.js import React from 'react'; function WithLoading(Component) { return function WihLoadingComponent({ isLoading, ...props }) { if (!isLoading) return ; return <p>Hold on, fetching data might take some time.</p>; }; } export default WithLoading;
CONDITIONALLY RENDER COMPONENTS
Suppose we have a component that needs to be rendered only when a user is authenticated — it is a protected component. We can create a HOC named WithAuth() to wrap that protected component, and then do a check in the HOC that will render only that particular component if the user has been authenticated.
other use cases
What is Redux Toolkit?
Redux Toolkitis our official, opinionated, batteries-included toolset for efficient Redux development. It is intended to be the standard way to write Redux logic, and we strongly recommend that you use it.
It includes several utility functions that simplify the most common Redux use cases, including store setup, defining reducers, immutable update logic, and even creating entire “slices” of state at once without writing any action creators or action types by hand. It also includes the most widely used Redux addons, like Redux Thunk for async logic and Reselect for writing selector functions, so that you can use them right away.
use contextAPI together with redux
theme goes in context - dark mode, light mode
redux is overkill for this
redux used for data
redux gives you safety that context doesn’t
middleware -
Redux middlewareprovides a third-party extension point between dispatching an action, and the moment it reaches the reducer. People useRedux middlewarefor logging, crash reporting, talking to an asynchronous API, routing, and more.
Redux-saga vs redux-thunk
async actions like network request - redux doesn’t give that out of the box, redux saga;
Redux-sagais areduxmiddleware library, that is designed to make handling side effects in yourreduxapp nice and simple. It achieves this by leveraging an ES6 feature called Generators, allowing us to write asynchronous code that looks synchronous, and is very easy to test.
The benefit of Redux-Saga in comparison to Redux-Thunk is that you can more easily test your asynchronous data flow. Redux-Thunk, however, is great for small projects and for developers who just entered into the React ecosystem. The thunks’ logic is all contained inside of the function.
React Testing
testing - establish projects - unit testing - testing a block of logic that has business logic in it,
could be as simple as writing just functions; test renderer,
enzime
mock render react tree for that component - snapshot which is like react component but as an object - you can use a mock data that you’re providing - important testing skill for react or native developers
jest - snapshot testing
you write your test, you run it once, and if your component if what you want, you commit your snapshot, etc and you save it in your commit and every time someone changes that componenet that test will run and if it doesn’t match you get a test error
you can have 1000 of snapshots, only runs on anything that has changed - component logic and it affected how the component rendered
storybook testing
you can use story book - story shots, solves part of the testing problem and design system problem, test components outside of the whole thing
Testing with storybook
https://storybook.js.org/docs/react/workflows/testing-with-storybook
end to end testing for react
end to end testing - detox for react native will build the app install on simulator and do it for actual app as opposed to snapshots
you can use jasmine for that for react
How To Write Snapshot Tests For React Components With Jest
Snapshot testing allows you to ensure your output continues to behave as expected. This is useful because as you revisit your code to make updates over time, there is an increased likelihood that those changes may cause something to break.
Unlike strict Test Driven Development (TDD), where the standard practice is to write failing tests first then write the code to make the tests pass, snapshot testing takes a different approach.
When writing snapshot tests for a React component, you first need to have code in a working state. Then, generate a snapshot of its expected output given certain data. The snapshot tests are committed alongside the component. Jest, a testing framework, will compare the snapshot to the rendered output for the test.
In the event of a failed test, it can mean two things. If the test results are unexpected, you may need to address an issue with your component. If the test results are expected, it may mean that the snapshot tests need to be updated to support the new output.
In this tutorial, you will be exploring snapshot tests and how you can use them to ensure your user interface (UI) does not change unexpectedly.