繁体   English   中英

React State 在不使用 setState() 的情况下发生变化

[英]React State is Changing Without Using setState()

我正在开发一个测验/测试网站。 当我转到下一个问题时,我想看到不同的问题,并且不想同时看到相同的答案。

  • 我有一个调用allWords的 state 数组变量。 此 state 将保留所有文字。
  • 我还有另一个 state 数组变量,它的调用类似于neverAskedWords 这个 state 将保留从未使用过的单词。

我正在创建一个新的数组变量并使用allWords中的 allWords 进行定义。 当我删除新数组变量中的任何记录时,该记录也在allWords变量中删除......为什么?

我想删除该临时数组中的任何记录,并将更新的版本保存到neverAskedWords state。 通过这种方式,我总是可以看到不同的问题。 这是我的代码。

const [allWords, setAllWords] = useState([])
const [neverAskedWords, setNeverAskedWords] = useState([])

async function getAllData(){
    
    axios
    .get(`http://127.0.0.1:3000/api/improve-language`)
    .then(res => {
      setAllWords(res.data)//defining allWords
      setNeverAskedWords(res.data)//defining neverAskedWords
      firstQuestionAndAnswers(res.data)//sending all datas by parameter, bacause when I'm trying to get datas by using `allWords` state, it would be undefined. That's why sending all data by parameter for the first time to set first question and answers.
    })
    .catch(err =>{
      console.log(err)
    })

  }

async function firstQuestionAndAnswers(wordsList){

    let neverAskedList = await wordsList //creating and defining temporary variables
    const allWordsList = await wordsList //creating and defining temporary variables

    //some not necessary codes for this issue
    const questionIndex = randomNumber(neverAskedList.length)
    const firstQuestion = neverAskedList[questionIndex]

    let firstAnswers = []
    for (let i = 0; i < 4; i++) {
      let answerIndex = randomNumber(allWordsList.length)
      firstAnswers[i] = allWordsList[answerIndex]
      allWordsList.splice(answerIndex, 1)//and here! I'm removing this record to prevent using it again next time, there will be different answers always
    }

    //some not necessary codes for this issue
    firstAnswers.push(firstQuestion)
    const randomisedAnswers = firstAnswers.sort(()=>Math.random() - 0.5)

    //some not necessary codes for this issue
    setQuestion(firstQuestion)
    setAnswers(randomisedAnswers)

    //and then here! I'm removing the used question in this time to prevent using it again, there will be different questions always and never see this question again 
    neverAskedList.splice(questionIndex, 1)
    setNeverAskedWords(neverAskedList)
    
  }

allWords不应该改变。 但是改变,因为为什么?

因此,我在您的代码中看到的最明显的事情是您正在修改相同的 object。 你应该做的是使用扩展运算符。

const [allWords, setAllWords] = useState([])
const [neverAskedWords, setNeverAskedWords] = useState([])

async function getAllData(){
    
    axios
    .get(`http://127.0.0.1:3000/api/improve-language`)
    .then(res => {
      setAllWords(res.data)//defining allWords
      setNeverAskedWords(res.data)//defining neverAskedWords
      firstQuestionAndAnswers(res.data)//sending all datas by parameter, bacause when I'm trying to get datas by using `allWords` state, it would be undefined. That's why sending all data by parameter for the first time to set first question and answers.
    })
    .catch(err =>{
      console.log(err)
    })

  }

async function firstQuestionAndAnswers(wordsList){
    // don't use await for js objects, should be used only with promises.
    // use spread operator to make copy of the wordList array so you never actually modify the original object
    let neverAskedList = [...wordsList]
    const allWordsList = [...wordsList]

    //some not necessary codes for this issue
    const questionIndex = randomNumber(neverAskedList.length)
    const firstQuestion = neverAskedList[questionIndex]

    let firstAnswers = []
    for (let i = 0; i < 4; i++) {
      let answerIndex = randomNumber(allWordsList.length)
      firstAnswers[i] = allWordsList[answerIndex]
      allWordsList.splice(answerIndex, 1)//and here! I'm removing this record to prevent using it again next time, there will be different answers always
    }

    //some not necessary codes for this issue
    firstAnswers.push(firstQuestion)
    const randomisedAnswers = firstAnswers.sort(()=>Math.random() - 0.5)

    //some not necessary codes for this issue
    setQuestion(firstQuestion)
    setAnswers(randomisedAnswers)

    //and then here! I'm removing the used question in this time to prevent using it again, there will be different questions always and never see this question again 
    neverAskedList.splice(questionIndex, 1)
    setNeverAskedWords(neverAskedList)
    
  }

如果你不明白为什么会这样,那么这里有一个简短的解释。 在 js 中,当您执行const a = { key: 'val' }时,您创建了一个变量,该变量引用实际存储 object 的 memory 块。 当您执行const b = a时,您正在创建另一个引用相同 memory 块的变量。 因此更新 1 会自动更改另一个。

暂无
暂无

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

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