簡體   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