1

Hey guys, i am working on a germany game called Kniffel. Its basically dice game.

So I am currently saving final score from thrown dice as State.

And then i would like to take that score from state and when i click a button it will save the score to specific element.

You can imagine it more when you check the code.

/* SAVING A SCORE TO STATE */
    const [totalValue, setTotalValue] = React.useState(0)
   /* HOW I GET IT */
    let total = 0

    React.useEffect(() => {

    dice.map(die => {
     if (die.isHeld) {
     total += die.value
    }

    })
    setTotalValue(total)
    }, [dice])

And i would like every time i click a button, the score from totalValue will pass to P element, where the button is located. Then a game is going to restart and next round you pass the score to different element.

There will me multiple score--inside divs, so i am thinking how should i approach this. Any help will be GOD!

if you guys have any ideas, let me know please.

UPDATE

I little bit change a code and made a another state with multiple scores:

// TOTAL
  const [totalValue, setTotalValue] = React.useState()

// TOTALS
const [totalValues, setTotalValues] = React.useState({
  ER1: 0,
  ER2: 0,
  ER3: 0,
  ER4: 0,
  ER5: 0,
  ER6: 0,
  Dreier: 0,
  Vierer: 0,
  Full: 0,
  Kleine: 0,
  Grobe: 0,
  Kniffel: 0,
  Chance: 0
})

Then i made a multiple functions, that will update the array.

function er1() {
  setTotalValues(prevState => {
    return {
      ...prevState,
      ER1: totalValue
    }
  })
}

function er2() {
  setTotalValues(prevState => {
    return {
      ...prevState,
      ER2: totalValue
    }
  })
}

function er3() {
  setTotalValues(prevState => {
    return {
      ...prevState,
      ER3: totalValue
    }
  })
}

.......etc

passing functions as props and passing them to buttons:

export default function Score({Score, Next, Values, er1, er2, er3}) {
    return (
        <div className="score--box">
        
            <div className="score--inside">
                <h3>1ER:</h3>
                <p>{Values.ER1}</p>
                <button onClick={() => {er1();Next()}}>Add score</button>
            </div>
        
    
            <div className="score--inside">
                <h3>2ER:</h3>
                <p>{Values.ER2}</p>
                <button onClick={() => {er2();Next()}}>Add score</button>
            </div>
            <div className="score--inside">
                <h3>3ER:</h3>
                <p>{Values.ER3}</p>
                <button onClick={() => {er3();Next()}}>Add score</button>
            </div>
        </div>
    )
}

When i look up to this, it will work but its not efficient how i would like it. Any idea how to simplify this?

1
  • You can display a value in the markup like this: <p>{props.Score}</p> But overall the question sounds like you just have an idea of something you want to build and are asking for general help to build it, which is too broad to be meaningfully answered here. You are encouraged to walk through some React tutorials and attempt to start building your application. Commented Mar 5, 2022 at 12:33

3 Answers 3

1

You can have a state like passTo inside the score component. Then add a button click event listener that identifies the button clicked. You can selectively display value of Score inside correct <p> with condition

// import useState
export default function Score({Score}) {

 const [passTo, setPassTo] = useState()

const handleClick = (btnId) => {
   setPassTo(btnId);
}

    return (
        <div className="score--box">
            <div className="score--inside">
                <h3>1ER:</h3>
                <p>{passTo==='1ER' && Score}</p>
                <button onClick={() => handleClick('1ER')}>Add score</button>
            </div>
            <div className="score--inside">
                <h3>2ER:</h3>
                <p>{passTo==='2ER' && Score}</p>
                <button onClick={() => handleClick('2ER')}>Add score</button>
            </div>
            <div className="score--inside">
                <h3>3ER:</h3>
                <p>{passTo==='3ER' && Score}</p>
                <button onClick={() => handleClick('3ER')}>Add score</button>
            </div>
        </div>
        )
    }

To further simplify, if there would be multiple scores like '1ER', '2ER' etc, , you can put those in an array and map through that

   // import useState
    export default function Score({Score}) {
       const scoreArr = ['1ER', '2ER', '3ER'] //As many needed, can pass as props too.
       const [passTo, setPassTo] = useState()
       
        const handleClick = (btnId) => {
           setPassTo(btnId);
        }
        return (
                <div className="score--box">
                     <div className="score--box">
                          {scoreArr.map((score) => {
                                  return ( 
                                  <div className="score--inside">
                                     <h3>`${score}:`</h3>
                                     <p>{passTo===score && Score} 
                                               </p>
                                     <button onClick={() => handleClick(score)}>Add score</button>
                                  </div>);
                   })}
               </div>
                </div>
                )
            }

Lemme know if it helps :)

Sign up to request clarification or add additional context in comments.

1 Comment

It works great, thanks. Just trying to figure out, when the Score state reset, the score inside element reset too, and i need to prevent that.
1

you can make a ScoreContainder component which contains the button and the <p></p> element

   export default function Score({id, score, setSelectedId, selectedId}){
       const onClick = ()=>{
           setSelectedId(id)
       }
       return <div className="score--inside">
                <h3>1ER:</h3>
                <p>{id===selectedId && score}</p>
                <button onClick={onClick} name='1ER'>Add score</button>
            </div>
   }

and in the parent component return this

     export const Parent(){
         const [totalValue, setTotalValue] = React.useState(0)
         const scoreRef = React.useRef(0)
         const [selectedId, setSelectedId] = React.useState()
         const getRandomnumber = ()=>{ // this causes rerender  
             scoreRef.current = Math.random() //or any other random funtion
             setTotalValue(scoreRef.current) 
         }
         const reset = ()=>{scoreRef.current = 0} //this won't cause rerender and reset the score value without showing the changes on the screen 
         return <div className="score--box">
             <Score id={0} score={totoalValue} selectedId={selectedId} setSelectedId = {setSelectedId}/>   
             <Score id={1} score={totoalValue} selectedId={selectedId} setSelectedId = {setSelectedId}/>
             <Score id={2} score={totoalValue} selectedId={selectedId} setSelectedId = {setSelectedId}/>
         
         </div>
     }

3 Comments

It works great, thanks. Just trying to figure out, when the Score state reset, the score inside element reset too, and i need to prevent that.
then you have to have two variables one is a state that causes rerendering and one with useRef that doesn't causes rerender
I change the code so can you check it now
0

If you can keep multi numbers it should better keep in an object instead number

const [totalValues, setTotalValue] = React.useState({})

and only one method can handle all objects
onClick=({target})=>{
totalValues[target.name]=target.value;
}

it just needs your element name to be an identity

return (
        <div className="score--box">
            <div className="score--inside">
                <h3>1ER:</h3>
                <p></p>
                <button onClick={onClick} name='1ER'>Add score</button>
            </div>
            <div className="score--inside">
                <h3>2ER:</h3>
                <p></p>
                <button onClick={onClick} name='2ER'>Add score</button>
            </div>
            <div className="score--inside">
                <h3>3ER:</h3>
                <p></p>
                <button onClick={onClick} name='3ER'>Add score</button>
            </div>
        </div>
        )

Finally you have this object {1ER:4,2ER:5,3ER:2,...}

this a sample

export const Score = () => {
  const [totalValues, setTotalValue] = useState({})
  const onClick = ({ target }) => {
    let randomScore = Math.floor(Math.random() * 6) + 1;
    totalValues[target.name] = randomScore;
    setTotalValue({...totalValues});
  }
  return (
    <div >
      <Label>{totalValues['2ER']}</Label>
      <div className="score--inside">
        <h3>1ER:</h3>
        <p>{totalValues.ER1}</p>
        <button onClick={onClick} name='ER1'>Add score</button>
      </div>
      <div className="score--inside">
        <h3>2ER:</h3>
        <p>{totalValues['ER2']}</p>
        <button onClick={onClick} name='ER2'>Add score</button>
      </div>
      <div className="score--inside">
        <h3>3ER:</h3>
        <p>{totalValues['ER3']}</p>
        <button onClick={onClick} name='ER3'>Add score</button>
      </div>
    </div>
  );
};

4 Comments

Where exactly you put your onClick function?
if tell me how to get a score I can help more. it's coming from props?
Ye score is coming from props as state. I am basically counting score every time dice change. let total = 0 React.useEffect(() => { dice.map(die => { if (die.isHeld) { total += die.value } }) setTotalValue(total) }, [dice])
I have written a sample for you

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.