【问题标题】:React Component is not re-rendering on the first state updateReact 组件不会在第一次状态更新时重新渲染
【发布时间】:2021-04-21 09:38:30
【问题描述】:

我目前正在进行一项非常简单的调查。您以“是”或“否”回答的那种。我已经列出了我在其自己的文件 (QuestionsList.js) 中放入和提取的问题。

这是我的问题列表:

const QuestionsList = [
"Do you believe in ghosts? ",
"Have you ever seen a UFO? ",
"Can cats jump six times their length? "
]
export default QuestionsList

我有我的应用程序:

import './App.css';
import Question from './components/Question';
import QuestionsList from './QuestionsList'
import { useState } from 'react';

function App() {
  let questionsList = QuestionsList
  const [current, setCurrent] = useState(0)
  const [currentQuestion, setCurrentQuestion] = useState(null)
  const [answers, setAnswers] = useState([])
  const [isStarted, setIsStarted] = useState(false)

  const onStartHandler = () => {
    setIsStarted(true)
    updateCurrentQuestion()
  }

  const updateCurrentQuestion = () => {
    setCurrentQuestion(questionsList[current])
  }

  const onYesHandler = () => {
    setCurrent(current => current += 1)
    setAnswers([...answers, 1])
    updateCurrentQuestion()
  }
  const onNoHandler = () => {
    setCurrent(current => current += 1)
    setAnswers([...answers, 0])
    updateCurrentQuestion()
  }
  return (
    <div className="App">
      {isStarted ? <Question question={currentQuestion} onYes={onYesHandler} onNo={onNoHandler} /> : null}
      <button onClick={onStartHandler}>START!</button>
      <button onClick={() => console.log(`Current: ${current}\nCurrent Question: ${currentQuestion}\nAnswers: ${answers}`)}>STATE LOG</button>
    </div>
  );
}

export default App;

还有我的问题组件:

import React from 'react'

const Question = (props) => {

    return (
        <div>
            <h2>{props.question}</h2>
            <div>
                <button onClick={props.onYes}>YES</button>
                <button onClick={props.onNo}>NO</button>
            </div>
        </div>
    )
}

export default Question

问题是每当我启动应用程序时。第一个问题出现了,但在第一次单击是或否时,状态会发生变化,问题也会发生变化,但第一次单击不会重新呈现问题。但是,每次后续单击都会重新渲染组件。我错过了什么?

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:
    
      const updateCurrentQuestion = (num) => {
        setCurrentQuestion(questionsList[num])
      }
       // within no/yes functions
       let num = current;
       setCurrent(old => old + 1);
       updateCurrentQuestion(num);
    
    

    这应该可以解决它。 UpdateCurrentQuestion 正在超越状态。

    【讨论】:

      【解决方案2】:

      当您调用 setCurrentQuestion() 时,它使用之前的 current 值,因为设置状态(setCurrent 所做的)是异步的。

      您不需要currentQuestion 状态,因为它派生自current。使用current 值从questionsList 获取问题。

      const { useState } = React;
      
      const Question = (props) => {
          return (
              <div>
                  <h2>{props.question}</h2>
                  <div>
                      <button onClick={props.onYes}>YES</button>
                      <button onClick={props.onNo}>NO</button>
                  </div>
              </div>
          )
      }
      
      function App({ questionsList }) {
        const [current, setCurrent] = useState(0)
        const [answers, setAnswers] = useState([])
        const [isStarted, setIsStarted] = useState(false)
      
        const onStartHandler = () => {
          setIsStarted(true)
        }
      
        const onYesHandler = () => {
          setCurrent(current => current += 1)
          setAnswers([...answers, 1])
        }
        const onNoHandler = () => {
          setCurrent(current => current += 1)
          setAnswers([...answers, 0])
        }
        return (
          <div className="App">
            {isStarted ? (
              <Question 
                question={questionsList[current]}
                onYes={onYesHandler}
                onNo={onNoHandler} />
              )
              :
              (
                <button onClick={onStartHandler}>START!</button>
              )
            }
          </div>
        );
      }
      
      const QuestionsList = [
        "Do you believe in ghosts? ",
        "Have you ever seen a UFO? ",
        "Can cats jump six times their length? "
      ];
      
      ReactDOM.render(
        <App questionsList={QuestionsList} />,
        root
      );
      <script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
      <script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
      <div id="root"></div>

      【讨论】:

        【解决方案3】:

        设置初始状态

        简单的解决方案:

        替换这个 const [currentQuestion, setCurrentQuestion] = useState(null)

        在这个const [currentQuestion, setCurrentQuestion] = useState(questionsList[current])


        顺便说一句 我看到了一些需要改进的地方。

        • onYesHandleronNoHandler 可以是一个获得布尔值的函数(true 或 false 表示是或否)
        • 您不需要保存导入的数据let questionsList = QuestionsList。您可以从导入中使用它作为QuestionsList

        但是对于初学者来说看起来还可以:)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-05-19
          • 2022-01-26
          • 2019-02-27
          • 2018-03-17
          • 1970-01-01
          相关资源
          最近更新 更多