DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’»

DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’» is a community of 968,873 amazing developers

We're a place where coders share, stay up-to-date and grow their careers.

Create account Log in
Cover image for React Custom Hooks - Sharing Logic Between Components
Lina Rudashevski
Lina Rudashevski

Posted on

React Custom Hooks - Sharing Logic Between Components

Below is an example of a React hook that is responsible for making a button turn purple in two different components. I use this is in my project which you can play here.

import { useState } from 'react';

 // hook code 
 function useMoveUpdate() {
  const [currentMove, setCurrentMove] = useState('');

   const newMove = (event) => {
    event.preventDefault();
    let move = event.currentTarget.value;
    let theVictim = null;
    if (event.currentTarget.value.includes('leave_comment')) {
      move = 'leave_comment';
      theVictim = event.currentTarget.id;
    }
    setCurrentMove(event.currentTarget.value);
  };

  return [currentMove, newMove];
}
import React from 'react';
import useMoveUpdate from '../hooks/CurrentMove';

function GameMoves({
  game, dispatch
}) {
  // component that uses the hook
  const [currentMove, newMove] = useMoveUpdate();

  return (
    <div>
      {['post_selfie', 'dont_post', 'go_live'].map(item => (
        <button
          className={currentMove === item ? 'button-color' : null}
          type="button"
          style={{ padding: '10px' }}
          value={item}
          onClick={newMove}
          disabled={!game.round_started}
        >
          {item.replace(/_/g, ' ')}
        </button>
      ))}
    </div>
  );
}

import React from 'react';
import { Phone } from '../images/iPhone';
import useMoveUpdate from '../hooks/CurrentMove';

function GameBox({ game, dispatch}) {
  // component that uses the hook
  const [currentMove, newMove] = useMoveUpdate();

  return (
    <div>
      <div style={{ display: 'flex', flexDirection: 'row' }}>
        {game.users.map(player => (
          <div style={{ margin: '1%' }} key={player.username}>
            {player.username}
            {!game.round_started && (player.started ? '!' : ' ?')}
            <div>
              {player.followers}
              {player.followers === 1 ? 'follower' : 'followers'}
            </div>
            <div style={{ marginBottom: '3px' }}>
              {player.stories}
              {player.stories === 1 ? 'story' : 'stories'}
            </div>
            <button
              onClick={newMove}
              id={player.id}
              disabled={!game.round_started}
              value={`leave_comment_${player.id}`}
              className={currentMove === `leave_comment_${player.id}` ? 'button-color' : null}
              type="button"
            >
              <Phone />
            </button>
            {' '}
          </div>
        ))}
      </div>
    </div>
  );
}

How it works.

const [currentMove, setCurrentMove] = useState('');

currentMove holds the value of which button should be purple and setCurrentMove executes the action, defined in the hook.

The state of the initial hook is an empty string, which means all of the buttons are green because the className is what changes when the button is clicked. The className dictates the CSS.

The hook returns [currentMove, newMove], and that is what useMoveUpdate returns in the components. Clicking the button executes newMove, the action that updates the button that is clicked and changes its color.

Here is an example of it working in my project:
Alt Text

Top comments (0)

This post blew up on DEV in 2020:

js visualized

πŸš€βš™οΈ JavaScript Visualized: the JavaScript Engine

As JavaScript devs, we usually don't have to deal with compilers ourselves. However, it's definitely good to know the basics of the JavaScript engine and see how it handles our human-friendly JS code, and turns it into something machines understand! πŸ₯³

Happy coding!