React Custom Hooks - Sharing Logic Between Components
Tags: react, javascript
Published: 2019-08-20 16:31:33

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](https://github.com/aduranil/selfies) which you can play [here](https://selfies-22b79.firebaseapp.com/). 

```javascript
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];
}
```

```javascript
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>
  );
}

```

```javascript
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.** 

```javascript
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](https://thepracticaldev.s3.amazonaws.com/i/cyeyfnir720u9s33iuu9.png)