Be A React Dev

Game View - Game Play Heading Rock Paper Scissors

19-Jun-2023


Amazon Prime

typescript plus react

What you will be building

Please check this link: Rock Paper Scissors Game

This app uses components from Chakra UI . You should check it out.

Game Play Heading

The game play heading is distinct from the game heading. The game heading is simply a page title. The play heading is feedback to the client about where the client is in the game play cycle. To communicate this, we will use some React hooks to help control the display of information to the client.

Let’s dive in to the code 🤿:

view/play-heading.tsx file

import React, { useEffect, useState } from 'react';
//  chakra-ui
import { Box, Heading, useColorModeValue } from '@chakra-ui/react';
//  interfaces
import { State } from '../state/interfaces';

interface Props {
  state: State;
}

const PlayHeading = (props: Props) => {
  const { state } = props;
  const { result } = state;
  const {
    computer: resultComputer,
    label: resultLabel,
    user: resultUser,
  } = result;
  const [win, setWin] = useState('neutral');
  const userWin = useColorModeValue('green.700', 'green.100');
  const userLose = useColorModeValue('red.700', 'red.100');

  //  user win effect
  useEffect(() => {
    if (resultComputer && !resultUser) {
      setWin('lose');
    }
    if (!resultComputer && resultUser) {
      setWin('won');
    }
    if (!resultComputer && !resultUser) {
      setWin('neutral');
    }
  }, [resultComputer, resultUser]);

  return (
    <>
      <Box display="flex" justifyContent="center" p={4}>
        <Heading
          as="h2"
          size="md"
          color={win === 'won' ? userWin : win === 'lose' ? userLose : ''}
        >
          {resultLabel || 'Awaiting Play'}
        </Heading>
      </Box>
    </>
  );
};

export default PlayHeading;

The first thing you will notice is that we are passing in props. Props are a variables passed in to functions. In React, the word ‘prop’ or ‘props’ is used to communicate any variable passed into a React component. It is simply a naming convention. Get used to it. Props is an object.

What is in props?

  const { state } = props;
  const { result } = state;
  const {
    computer: resultComputer,
    label: resultLabel,
    user: resultUser,
  } = result;

PRO TIP: what we did up there is called ‘destructuring’.

We expect to find a state, and within state we expect to find a result. Within result we expect to find computer, label and user. We alias these to resultComputer, resultLabel and resultUser respectively. This is technically not required in this file, but I find doing this can save time later because it can be difficult to foresee if we might need another part of the state object - such as the games key - which also contains computer and user.

These are defined in the State interface which we have already defined here.

useColorModeValue and useState and useEffect

  const [win, setWin] = useState('neutral');
  const userWin = useColorModeValue('green.700', 'green.100');
  const userLose = useColorModeValue('red.700', 'red.100');

  //  user win effect
  useEffect(() => {
    if (resultComputer && !resultUser) {
      setWin('lose');
    }
    if (!resultComputer && resultUser) {
      setWin('won');
    }
    if (!resultComputer && !resultUser) {
      setWin('neutral');
    }
  }, [resultComputer, resultUser]);

OK. useColorModeValue is from Chakra-UI. It sets a color based on whether the client is using ‘light’ or ‘dark’ mode. We don’t discuss how to make this feature work in this tutorial.

We use useState to set a string. The default state value is ‘neutral’. But, we use useEffect to respond to changes to resultComputer and resultUser.

We can use the values of resultComputer and resultUser to set the state of ‘win’. If you are understanding the code correctly you will notice ‘win’ has three possible states. You may also notice that my code is verbose. That means that the next person who comes along to read this code should have no question about what this code is supposed to do. This could be refactored out to a helper function which could reduce the complexity of the useEffect content a little, but it is not essential.

ternary

  color={win === 'won' ? userWin : win === 'lose' ? userLose : ''}

I did something naughty here. If you are wondering what you can read ‘no nested ternary’ .

However, sometimes it’s easier to just get shit done. That said, you should be able to look at this code and notice that it is hard to read. And that is the cruxt of why nested ternaries suck dead dog’s balls.

In this case I chose to use a nested ternary because it is not too shit in this specific case. The line is not super long and not super confusing. But, it could be wise to refactor this out to a simple helper function and return the result of the helper function, especially if the logic required became more convoluted than it currently is.

Heading content

  {resultLabel || 'Awaiting Play'}

So this little bit of code is about knowing how to plan ahead and knowing how to use Javascript to respond to falsey values.

The result label - by default - is an empty string (you can check this for yourself, the link is here).

What magic is this? Well, what the code says without saying it is: if resultLabel has a value, show resultValue OR (‘||’) if resultLabel does not have a value, show ‘Awaiting Play’.

Here's a list of JavaScript's falesy values .

OK. Done.


Get Cool Swag

If you are finding this content useful (or maybe you are just a nice person or maybe you just like my merch) I would be greatful if you headed over to my shop and make a purchase or two. All proceeds will go towards making more courses.

If there’s merch missing that you would like, let me know (click this: Make Something For Me ) and I’ll try to make it for you.

mom’s little shits times three

Mom’s little shits times three

You can buy this product or you can check out my shop of products.


About

The Author Guy

Find Me

Rob Welan <rob.welan@beareact.dev>FacebookKo-FiLinkedInMediumPatreonRSS FeedStack OverflowX

Tech In Use

Be A React Dev

© 2024 Be A React Dev. All rights reserved.