繁体   English   中英

为什么“React App”按钮(激活 useState 功能)在某些使用后会崩溃?

[英]Why does 'React App' button (that activates useState function) crashes after some uses?

我正在参加 Full Stack Open 的练习。 任务是创建一个按钮,从他们给你的一个充满字符串的数组中显示一个随机的“轶事”。 练习变得更加复杂,他们要求您为每个“轶事”(我称之为“initialVotes”)创建一个带有投票的数组,并有一个添加投票的按钮(他们还要求您显示具有最高价值的那个) )。

现在,我将给出练习的每一个细节,因为我没有意识到在完成所有操作后它可能会崩溃。 问题很奇怪,一切都“正常”,直到您单击“下一个轶事”按钮几次,然后它停止工作(每次重新加载页面时,在崩溃之前您可以使用它的次数都会改变,这使得它更奇怪的imo)。 如果您使用“添加投票”按钮,它可能会再次起作用(甚至想不出为什么)。

这是代码:

import { useState } from 'react'
import React from 'react'

const firstIndex = Math.floor(Math.random() * 7)

const App = () => {

  const anecdotes = [
    'If it hurts, do it more often.',
    'Adding manpower to a late software project makes it later!',
    'The first 90 percent of the code accounts for the first 10 percent of the development time...The remaining 10 percent of the code accounts for the other 90 percent of the development time.',
    'Any fool can write code that a computer can understand. Good programmers write code that humans can understand.',
    'Premature optimization is the root of all evil.',
    'Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.',
    'Programming without an extremely heavy use of console.log is same as if a doctor would refuse to use x-rays or blood tests when diagnosing patients.'
  ]

  const [selected, setSelected] = useState(firstIndex)

  const newIndex = Math.floor(Math.random() * 7)

  // We could use: const initialVotes(Uint8Array)
  const n = 7  // arbitrary length
  const initialVotes = Array(n).fill(0)

  const [votes, setVotes] = useState(initialVotes)

  const addVote = (index) => {
    const vote = votes[index] + 1
    setVotes([
      ...votes.slice(0, index),
      vote,
      ...votes.slice(index + 1, n)
    ])
  }

  const mostVotes = Math.max(...votes);
  const mvIndex = votes.indexOf(mostVotes)

  console.log(newIndex)
  console.log(anecdotes[selected])

  return (
    <React.Fragment>
      <h1>Anecdote of the day</h1>
      <h4>{anecdotes[selected]}</h4>
      <p>has {votes[selected]} votes</p>
      <button type="button" onClick={() => addVote(selected)}>vote</button>
      <button type="button" onClick={() => setSelected(newIndex)}>next anecdote</button>
      <h1>Anecdote with most votes</h1>
      <p>The anecdote with most votes is: <mark>{anecdotes[mvIndex]}</mark></p>
      <p>With "{mostVotes}" votes</p>
    </React.Fragment>
  )
}

export default App

newIndex与当前selected状态相同时,执行setSelected(newIndex)会导致组件重新渲染失败。 selected的新值应该不是 state 中当前值,以便状态设置器工作。

一种方法是:

let newIndex;
do {
  newIndex = Math.floor(Math.random() * 7);
} while (newIndex === selected);

 const { useState } = React; const firstIndex = Math.floor(Math.random() * 7) const App = () => { const anecdotes = [ 'If it hurts, do it more often.', 'Adding manpower to a late software project makes it later!', 'The first 90 percent of the code accounts for the first 10 percent of the development time...The remaining 10 percent of the code accounts for the other 90 percent of the development time.', 'Any fool can write code that a computer can understand. Good programmers write code that humans can understand.', 'Premature optimization is the root of all evil.', 'Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.', 'Programming without an extremely heavy use of console.log is same as if a doctor would refuse to use x-rays or blood tests when diagnosing patients.' ] const [selected, setSelected] = useState(firstIndex) let newIndex; do { newIndex = Math.floor(Math.random() * 7); } while (newIndex === selected); // We could use: const initialVotes(Uint8Array) const n = 7 // arbitrary length const initialVotes = Array(n).fill(0) const [votes, setVotes] = useState(initialVotes) const addVote = (index) => { const vote = votes[index] + 1 setVotes([ ...votes.slice(0, index), vote, ...votes.slice(index + 1, n) ]) } const mostVotes = Math.max(...votes); const mvIndex = votes.indexOf(mostVotes) return ( <React.Fragment> <h1>Anecdote of the day</h1> <h4>{anecdotes[selected]}</h4> <p>has {votes[selected]} votes</p> <button type="button" onClick={() => addVote(selected)}>vote</button> <button type="button" onClick={() => setSelected(newIndex)}>next anecdote</button> <h1>Anecdote with most votes</h1> <p>The anecdote with most votes is: <mark>{anecdotes[mvIndex]}</mark></p> <p>With "{mostVotes}" votes</p> </React.Fragment> ) } ReactDOM.createRoot(document.querySelector('.react')).render(<App />);
 <script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script> <script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script> <div class='react'></div>

或者您可以生成一个从 0 到 5 而不是 0 到 6 的随机数,如果生成的数字等于当前selected ,则将 6 分配给newIndex

暂无
暂无

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

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