Be A React Dev

Game View - Game Controls Resets Rock Paper Scissors

05-Jul-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.

Introduction

This is one of the more complicated view components in that it includes game controllers. Rather than merely showing game display, this component provides mechanisms for game control also. We will get into this.

First, here is the code.

view/game-controls-resets.tsx

import React, { useEffect, useState } from 'react';
//  chakra-ui
import { Box, Button, SimpleGrid } from '@chakra-ui/react';
//  react icons
import { FaGamepad } from '@react-icons/all-files/fa/FaGamepad';
import { FaTrashAlt } from '@react-icons/all-files/fa/FaTrashAlt';
//  components
import StandardDivider from '../../../components/standard-divider';
//  interfaces
import { SetState, State } from '../state/interfaces';
//  local actions
import setClearAll from '../actions/set-clear-all';
import setClearGame from '../actions/set-clear-game';

interface Props {
  setState: SetState;
  state: State;
}

const GameControlsResets = (props: Props) => {
  const { setState, state } = props;
  const [columns, setColumns] = useState(1);

  // columns effect
  useEffect(() => {
    if (columns === 1) {
      if (state.result.label !== '' && state.games.total > 0) {
        setColumns(2);
      }
    }

    if (columns === 2) {
      if (state.result.label === '' || state.games.total === 0) {
        setColumns(1);
      }
    }
  }, [state.result.label, state.games.total]);

  return (
    <>
      {(state.result.label !== '' || state.games.total > 0) && (
        <>
          <StandardDivider />
          <SimpleGrid columns={[columns, null, columns]} spacing={4}>
            {state.result.label !== '' && (
              <Box display="flex" justifyContent="center">
                <Button
                  aria-label="clear game"
                  leftIcon={<FaGamepad />}
                  onClick={() => setClearGame({ setState })}
                  variant="solid"
                >
                  New Game
                </Button>
              </Box>
            )}

            <Box display="flex" justifyContent="center">
              <Button
                aria-label="clear all"
                leftIcon={<FaTrashAlt />}
                onClick={() => setClearAll({ setState })}
                variant="outline"
              >
                Clear All
              </Button>
            </Box>
          </SimpleGrid>
        </>
      )}
    </>
  );
};

export default GameControlsResets;

Imports

This component requires React, useEffect and useState from react. It also requires Box, Button and SimpleGrid from Chakra-UI, and a couple icons from Font Awesome within react icons.

Next it imports a standard shared component from the components bucket, the StandardDivider, then the interfaces for SetState and State, and finally a couple of actions for game control.

Interface

This interface requires SetState and State for typing Props.

Function

Next we create our fat arrow function and call it GameControlsResets. This function accepts props (and props contains setState and state).

Within the function, first the props are desctructured exposing setState and state and then a local state for column display control is created with useState.

The useState feature is pretty simple. A default state of 1 is set (1 column needed for display), and the state is exposed with the columns property and the setting function is exposed by the setColumns function.

Columns Effect

The function then utilises the useEffect hook to decide how to respond to changes in state result label and state game total. Do we need to refer to the state result label? Probably not really. There are simpler ways to write this rule set but the way it is written is clear as to what is required. Do we need to refactor it to save lines of code or appear smarter to our colleagues? Meh.

Return

The function returns the view next. The view only returns something if there is at least one game played.

Assuming there is a game played the output is wrapped in a fragment in order to meet React component return rules.

Within the fragment, the StandardDivider is used “as is”. A SimpleGrid is used and the amount of columns displayed at various screen sizes is chosen based on the columns state value.

The state result label is checked for a value in case the New Game button should be displayed or not. The state.games.total is already checked for a value so there is no need to check this value again. The Clear All button will be displayed by default at this point.

The Buttons are placed inside Box which have their content centered.

The Buttons themselves are given aria labels just to make sure that screen readers can recognise them for vision impaired people. Each button is given an onClick handler to respond to the click event.

The next article will discuss the actions in more detail.

:-)


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.

The System Is Fixed T-Shirt

The System Is Fixed T-Shirt

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.