React js 18 How do I make sure I'm building responsive applications?
ith so many different screen sizes out there I'd like to make my applications as responsive as I can. I've been using React Native for the most part, and I have the iPhone 13 Pro simulator open for testing purposes. But let's say I want someone with an iPhone XR, or Pixel 6 to use my apps. What should be done when styling components to make sure they will adapt automatically to new screen sizes, since it would be unreasonable to style each component for each screen?
Should I be using percentages, flexboxes, or something else? This is one area I struggle with when working on the frontend.
You're right about it being unreasonable to style each component for each screen size, so that leaves us with flexboxes and percentages.
Try not to actually define the width of anything(unless it's so small that'll never be greater than your screen) and just let the content fill in the empty space.
You can should always simulate on different screen sizes too just to make sure everything is correct, but generally I like to start on the smallest screen size. If the content fits on a small screen it'll fit on a larger screen.
So React is all about creating reusable bits of presentation logic (components) and using them to compose views. Now that we have hooks, we can actually simplify this composition further: hooks allow us to encapsulate certain behaviors, often composed of multiple hooks, into functions that integrate directly into React’s renderer (using the new React Fiber
, which we won’t dive into here) to automatically update the components using them.
useState
useState
allows us to have stateful functional components! you call useState(initialValue)
and it returns a pair of [state, setState]
. Because it returns an array and not an object, you are free to name these references however you please. Most importantly, useState
hooks into React DOM and triggers a render when you use the setState
function returned from it, so it works just like this.setState
would for class components.
useEffect
useEffect
will normally run its code every time a component re-renders, however it accepts a second argument, an array of variables, that inform useEffect
that it should only re-run when a value inside the array is changed. When provided an empty array, it will never re-run, so it behaves exactly like componentDidMount
! The return value for useEffect
should be a cleanup function, if required, so that it can be run before the effect is re-run, or the component is being removed from the DOM. Here we specify an anonymous function that will remove the event listener when this component is un-mounting (sound familiar? this is what we’ve been doing inside of componentWillUnmount
).
Now this seems pretty good, but what happens if there are multiple places where things on the page need to render based on a breakpoint? We shouldn’t be setting up new event listeners for the same event every time one of these components is mounting, especially since we only have one window resize to listen for.
useContext
One of the ways hooks have really made things better is when using the Context API. Previously, using Context required using Consumer and Provider components, and utilizing the Consumer in any component that needed access to the value. This led to devs creating Higher Order Components for providing context as props (for example, react-redux
's connect
) or simply very verbose code. Now, with useContext
, we no longer have to use Context.Consumer
Components to make children aware of values from Context.
Let’s rewrite the above component, using Context and an App-wide WindowDimensionsProvider
.
export default WindowDimensionsProviderexport const