【问题标题】:How do I render different data of an onClick event without updating the previous render?如何在不更新先前渲染的情况下渲染 onClick 事件的不同数据?
【发布时间】:2021-07-27 22:19:08
【问题描述】:

我正在使用 React/Context API/UseReducer 创建一个基于文本的 rpg,但首先我想练习使用 useState 以从 onclick 事件中呈现对象。到目前为止,我设法从数组中渲染了一个对象,而显示的数据由我单击的按钮决定。问题是,每当我渲染一个对象并点击另一个按钮时,都会渲染新对象,而前一个对象会更新为我当前单击的对象。

例如,我有 8 个选项可供选择:弱打击 1-4、中打击 1-2、强打击和发射打击。当我单击 Weak Strike 1 时,它会呈现在页面上。当我点击 Mid Strike 1 时,它也会在页面上呈现,但 Weak Strike 1 变为 Mid Strike 1,所以现在我有两个 Mid Strike 1。

我需要一种方法来在页面上同时呈现 Weak Strike 1 和 Mid Strike,而无需更新其中一个或另一个以相互匹配。

代码:状态挂钩

const [name, setName] = useState(rpActions.strike)  //Used to set and update a strike action

const [count, setCount] = useState(0)  //Used to add a component after one button click

代码:onClickHandler

const onClickHandler = (e) => {

    setCount(count + 1)
    setName({...name, name: e.target.value})
    console.log(e.target.value)

 }

代码:渲染逻辑

 <button className="w3-button w3-purple" value={name[0].name}  onClick={onClickHandler}>{name[0].name}</button>
      <button className="w3-button w3-purple" value={name[1].name}  onClick={onClickHandler}>{name[1].name}</button>
      <button className="w3-button w3-purple" value={name[2].name}  onClick={onClickHandler}>{name[2].name}</button>
      <button className="w3-button w3-purple" value={name[3].name}  onClick={onClickHandler}>{name[3].name}</button>
      <button className="w3-button w3-purple" value={name[4].name}  onClick={onClickHandler}>{name[4].name}</button>
      <button className="w3-button w3-purple" value={name[5].name}  onClick={onClickHandler}>{name[5].name}</button>
      <button className="w3-button w3-purple" value={name[6].name}  onClick={onClickHandler}>{name[6].name}</button>
      <button className="w3-button w3-purple" value={name[7].name}  onClick={onClickHandler}>{name[7].name}</button>

 
{[...Array(count)].map((_, i) => <BattleSelection key={i} stkName2={name.name} />)}      

【问题讨论】:

    标签: javascript arrays reactjs use-state buttonclick


    【解决方案1】:

    如果我理解正确,您的 name 变量应该是数组而不是对象。

    您的BattleSelection 组件读取对象name,每次单击按钮时都会更新该对象。计数的数量无关紧要,您总是在读取最后点击的值。

    另外,由于 rpActions 是一个常数,你不需要把它放在状态变量上:

    const [strikes, setStrikes] = useState([])  //Used to set and update a strike action
    
    // you can also use value here, but maybe your strike object has more attributes that you might need.
    const onClickHandler = (newStrike) => {
        setStrikes(_strikes => [..._strikes, newStrike])
        console.log(newStrike)
    }   
    
    {rpActions.map(d => (
      <button className="w3-button w3-purple" 
        value={d.name}  // not necessary anymore
        onClick={() => onClickHandler(d)}
       >
        {d.name}
       </button>
    ))}
    
    {strikes.map((d) => <BattleSelection key={d.name} stkName2={d.name} />)} 
    

    【讨论】:

      【解决方案2】:

      name 仅存储最近点击的罢工。映射数组时,name.name 在每次迭代中具有相同的值。

      相反,您希望了解罢工历史。创建一个数组并在每次点击时追加一个新项目。

      const [names, setNames] = useState([]);
      
      const onClickHandler = (e) => {
      setNames([...names, { name: e.target.value }])
      }
      

      渲染:

      names.map((item, i) => <BattleSelection key={i} stkName2={item.name} />)}      
      

      【讨论】:

      • 我在这里使用了一些逻辑来使其与 Pedro 解决方案所施加的逻辑一起工作。谢谢。
      猜你喜欢
      • 2018-09-19
      • 2020-08-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-09
      • 2021-09-22
      • 2020-09-14
      • 2022-07-30
      相关资源
      最近更新 更多