skip to Main Content

I am learning and practicing hooks useState in react js. For example, when declaring a state variable like this,

const [votes, setVotes] = useState(0)

I know that the 0 value in useState() means that votes is initialized with starting value of 0. However, advancing a little bit, like this,

const [votes, setVotes] = useState(() => Array(fruits.length).fill(0))

Given an array,

const fruits = ["kiwi", "banana", "mango", "apple", "durian"]

I am a little confused with the Array in the second state variable wrapping fruits.length, why do we have to wrap it with Array ? fruits is already an array. And just to make sure that I understand, the .fill(0) means that we will initialize every element in the array fruit with 0? Am I right ? To give a context, I have an array fruits and two buttons, one is to vote, and the other is to select randomly the next fruit. Every time I vote, the vote will increase and when I click the other button, random fruits will be displayed and the vote will be 0 for fruits that haven’t got voted. This is the vote button code,

const handleVotes = () => { 
    setVotes((votes) => 
      votes.map((vote, index) => index === selected ? vote + 1 : vote)
    )
 }

2

Answers


  1. Array(array.length).fill(0) is a JavaScript expression that creates a new array filled with a specified value. The expression creates an array with the length equal to the length of the array variable passed as an argument. The .fill(0) method is then used to fill the entire array with the value 0.

    Here’s an example:

    const array = [1, 2, 3, 4, 5];
    const newArray = Array(array.length).fill(0);
    console.log(newArray);
    // Output: [0, 0, 0, 0, 0]
    

    In this example, array is an array with 5 elements, so Array(array.length).fill(0) creates a new array with 5 elements, all filled with the value 0.

    I hope this helps!

    Login or Signup to reply.
  2. Mapping over the entire array of fruits is rather inefficient. We can use a Map which allows us to create a mapping between fruits and their votes. This allows us to update a fruit directly, without having to evaluate a condition against each element. Run the demo below and vote for your favourite!

    function App({ fruits }) {
      const [selected, setSelected] = React.useState(fruits[0])
      const [votes, setVotes] = React.useState(() => new Map)
      const select = fruit => event => {
        setSelected(fruit)
      }
      const vote = event => {
        setVotes(vs =>
          new Map(vs).set(selected, (vs.get(selected) || 0) + 1)
        )
      }
      return <div>
        {fruits.map(f =>
          <button
            onClick={select(f)}
            className={selected == f ? "selected" : ""}
            children={f}
          />
        )}
        <button onClick={vote} children="vote" />
        <pre>{JSON.stringify(Object.fromEntries([...votes]))}</pre>
      </div>
    }
    
    ReactDOM.render(<App fruits={["🥝","🍎","🍑"]} />, document.body)
    .selected { border-color: teal; }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.0/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.0/umd/react-dom.production.min.js"></script>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search