2

This example simulates a coin toss.
I would like to randomize the initial state of the coin. The first time the page is loaded it could show heads. The next time, tails. To do so, I am using a random number generated by the Math method and a conditional to determine the face of the coin based on the random number (even number shows heads, odd shows tails).
The value needs to be displayed upon the initial render.

I also want to store the value in state using React's Hooks to use later in my app. How can I set a randomized initial state value using hooks?

Here is the code that I am working with. It currently does not function and I'm not sure what I am doing incorrectly to achieve my goal:

import React, { useState } from 'react';
import './App.css';

function App() {

  const [coin, setCoin] = useState(randomizePlayer())

  const randomizePlayer = () => {
    let number = Math.floor(Math.random() * 10) + 1
    return (number % 2 === 0) ? setCoin('Heads') : setCoin('Tails')
  }

    return (
      <div className="App">
        The coin is showing {coin}
      </div>
    );
  }

export default App;

I'm brand new to the hooks API and am using this exercise to learn.

Any help is appreciated!

Jacob Crocker
  • 75
  • 1
  • 7
  • It's unclear how want it to work. A state should be preserved between page reloads, correct? You need persistent state then. This is not specific to hooks. Since you're new to hooks, how would you do the same thing with a class and `this.state`? – Estus Flask Apr 16 '19 at 21:22
  • Hey, estus. I appreciate the response! I understand that what I am trying to accomplish may not be best practice. I have added a comment to Jake Worth's answer and I am curious of your thoughts on it. – Jacob Crocker Apr 17 '19 at 13:48
  • I'm still not sure what exactly you're trying to accomplish. If the answer works for you that's ok but this is not coherent with what you stated in the question. Can you provide an example of how you would implement this logic without hooks? This will give a clear idea about what you want. – Estus Flask Apr 17 '19 at 13:59

1 Answers1

3

I would rewrite this code as follows:

const randomizePlayer = () => {
  const number = Math.floor(Math.random() * 10) + 1
  return (number % 2 === 0) ? 'Heads' : 'Tails'
}

function App() {
  const [coin, setCoin] = useState(randomizePlayer())

  return (
    <div className="App">
      The coin is showing {coin}
    </div>
  );
}

randomizePlayer does not need to call setState; let it just return a value. useState can use that value as its initial state.

Also to clarify: useState gets called just once. If you want coin to have a different value, the way to do that with this setup is to remount the component (reload the page).

State hooks docs

Jake Worth
  • 5,490
  • 1
  • 25
  • 35
  • This achieves what I was looking for (however, coin should be declared after the randomiziePlayer function since it calls the function). Thanks for your help! I'm curious though. Based on estus's comment on the question, is this not best practice? – Jacob Crocker Apr 17 '19 at 13:24
  • I think estus's question alludes to the fact that the misunderstanding here is not about hooks. In a class component you wouldn't see `setState` called inside `constructor` because initializing state directly via `this.state =` is part of the reason `constructor` exists. To quote the React docs: "You should not call setState() in the constructor(). Instead, if your component needs to use local state, assign the initial state to this.state directly in the constructor". `useState` is another way to initialize state, so I would not call this a best practice. – Jake Worth Apr 17 '19 at 14:25
  • And great call on declaring `randomizePlayer` before assigning `coin`, Jacob! Since that function doesn't know about `App`'s state anymore, we can move it outside of the function. Edited. – Jake Worth Apr 17 '19 at 14:50