繁体   English   中英

React JS - 如何将 state 的值添加到特定元素

[英]React JS - How to add value from state to specific element

大家好,我正在开发一款名为 Kniffel 的德国游戏。 它基本上是骰子游戏。

所以我目前将掷骰子的最终得分保存为 State。

然后我想从 state 中获取该分数,当我单击一个按钮时,它将分数保存到特定元素。

当你检查代码时,你可以想象更多。

/* 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])

我希望每次单击按钮时,totalValue 的分数将传递给按钮所在的 P 元素。 然后游戏将重新开始,下一轮你将分数传递给不同的元素。

我会有多个分数——在 div 中,所以我在想我应该如何处理这个问题。 任何帮助将是上帝!

如果你们有任何想法,请告诉我。

更新

我稍微更改了一个代码并制作了另一个具有多个分数的 state:

// 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
})

然后我做了一个多个函数,它将更新数组。

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

将函数作为道具传递并将它们传递给按钮:

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>
    )
}

当我看这个时,它会工作但效率不高。 知道如何简化这个吗?

您可以在评分组件中使用 state 之类的passTo 然后添加一个按钮单击事件侦听器,用于标识单击的按钮。 您可以根据条件在正确的<p>中选择性地显示Score的值

// 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>
        )
    }

为了进一步简化,如果有多个分数,如“1ER”、“2ER”等,您可以将它们放在一个数组中,然后将 map 放入数组中

   // 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>
                )
            }

让我知道它是否有帮助:)

您可以制作一个包含按钮和<p></p>元素的 ScoreContainder 组件

   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>
   }

并在父组件中返回这个

     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>
     }

如果您可以保留多个号码,最好保留一个 object 而不是号码

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

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

它只需要你的元素名称是一个身份

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>
        )

最后你有这个 object {1ER:4,2ER:5,3ER:2,...}

这是一个样本

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM