Now what about the styling,
what about these buttons? Now for these buttons,
you might notice that you now have a strange behavior
if you wrote it back to portrait mode, also here on Android. On the other hand if we change something and
undo that just so that the app restarts and we start in portrait mode, you'll see it looks good
but now if we go to landscape mode, it looks bad again.
So basically, the width of our buttons gets logged in when the app starts and doesn't adjust when our
screen size changes and of course it changes when we rotate the device because width and height get
swapped,
so we have more width available if we're in landscape mode than we have in portrait mode.
The problem is that currently on the start game screen when we set the width of our buttons which we
do down there, we use dimensions get and this and that's very important to keep in mind, this is only
calculated when your app starts.
So when the app starts for the first time, this has a look at the available width and if it starts in
portrait mode,
that's the portrait mode width, if it starts in landscape mode, it's the landscape mode width and it logs
this in and when you then rotate the device and if you then rotate the device, this doesn't recalculate.
Now of course you would want this to recalculate and there is a simple fix for that.
If you have a width or height, anything you get from dimensions which should respect orientation changes,
so which should recalculate when the orientation changes, then you should not use dimensions width down
there in your stylesheet but instead, you need to manage the width or whatever property it is
that can change dynamically and that should re-render the UI when it changes with state.
So here in the start game string, we already have useState,
we can now also manage our button width here, set button width with useState and initialize this to dimensions
get window width divided by four which is the default
I started with.
Now you can set up a listener here on dimensions, instead of using get by calling add event listener
and listen to the change event which fires whenever the dimensions change which typically is the case
when the user rotates the device.
So here, we can set up a function, update layout for example which is a function in which I call set button
width and set it again to my width here but the dimensions width will be different based on the
width of the screen
when we rotate it and it's this function which I want to call here, so it's update layout which I want to
call here without parentheses here because we just want to point at this function
so that it's called for us when the dimensions change and this will make sure that this re-runs whenever
our dimensions change and therefore this component will re-render.
Now we just have to make sure we use that dynamically recalculated button with state here.
We can do this by using inline styles instead of a stylesheet object.
Now if you had other styles set up for the button which do not depend on the dimensions, then you could
leave them here in the stylesheet of course,
in this case I don't have that though, so I'll just comment this out and you could then merge that with some
inline styles. Here since we have no default other styles,
I'll just replace this stylesheet object we're pointing at with an inline style object where I set
width equal to button width and do the same of course for my second button and with that,
we now have styling that changes whenever we rotate the device.
So if we save this, you'll see this now looks good no matter how we rotate
this, also on Android because this gets re-rendered.
Now one important note here though, right now at the moment I'm setting up a bunch of event listeners
here,
I always add a new event listener whenever this component re-renders and that's not what I
want to do
and we can use use effect which is also built into React and which you should be aware of to have
code that we run whenever our component re-renders.
So now I can use use effect here and the function which I want to run on every re-render is a function which
in the end creates this update layout function here and adds my event listener,
so I'll cut this and add it here in use effect function and if we then return something here in use
effect, that's our clean up function which runs right before use effect runs in and there,
I want to clean up my listener because here I can then call dimensions remove event listener
change for update layout.
So now we clean this up and set up a new one when our component re-renders, clean up the old one, set up
a new one and therefore we always only have one running event listener.
If we do it like this, that's simply cleaner and therefore if we now save this and we go back, we have
the same behavior as before but now in a clean way by utilizing useState and use effect and most importantly,
the event listening capabilities of the dimensions API which allow us to not only set dimensions once
but recalculate them when they change.