Javascript 为什么React应用程序状态不在此处重新呈现?如何使状态及时更新

Javascript 为什么React应用程序状态不在此处重新呈现?如何使状态及时更新,javascript,reactjs,state,use-effect,Javascript,Reactjs,State,Use Effect,我想弄清楚这是怎么回事 我有一个“pageCounter”变量,用于跟踪当前页面(单击上一页/下一页按钮时更新),当更新时,我希望将选项卡的标题更改为新页面数据 单击“下一步”按钮时,它不会渲染,除非我单击两次,并且控制台日志显示它尚未更新。但当我点击“下一步”后点击“日志”按钮时,它会说它已经更新了吗 我已经做了研究,并假设这是由于“setState”函数的异步性质造成的。但是,我不知道如何解决这个问题 我尝试将updateTitles函数放入useffect钩子中,但无论我是将函数的内容复制

我想弄清楚这是怎么回事

我有一个“pageCounter”变量,用于跟踪当前页面(单击上一页/下一页按钮时更新),当更新时,我希望将选项卡的标题更改为新页面数据

单击“下一步”按钮时,它不会渲染,除非我单击两次,并且控制台日志显示它尚未更新。但当我点击“下一步”后点击“日志”按钮时,它会说它已经更新了吗

我已经做了研究,并假设这是由于“setState”函数的异步性质造成的。但是,我不知道如何解决这个问题

我尝试将updateTitles函数放入
useffect
钩子中,但无论我是将函数的内容复制到钩子中,还是在钩子中调用函数,都会出现错误

我错过了什么

updatetiles
的内容放入
useffect
时,我遇到的错误是:

超过最大更新深度

        import React, { useState, useEffect } from "react";

function Options() {
  // Component States
  const [pageCounter, setPage] = useState(1);
  const [optionTitles, setOptionTitles] = useState({
    Option1: "Page 1.11",
    Option2: "Regular House Cleaning",
    Option3: "Other Clean"
  });
  //Component Variables
  const pageOneTitles = {
    Option1: "Page 1.1",
    Option2: "Regular House Cleaning",
    Option3: "Other Clean"
  };
  const pageTwoTitles = {
    Option1: "Page 2.1",
    Option2: "Blah12",
    Option3: "Blah13"
  };
  const pageThreeTitles = {
    Option1: "Page 3.1",
    Option2: "Nins",
    Option3: "Pottao"
  };

  useEffect(() => {
    switch (pageCounter) {
      case 1:
        setOptionTitles(pageOneTitles);
        break;
      case 2:
        setOptionTitles(pageTwoTitles);
        break;
      case 3:
        setOptionTitles(pageThreeTitles);
        break;
      default:
        console.log("default");
        break;
    }
  }, [pageCounter, pageOneTitles, pageTwoTitles, pageThreeTitles]);

  function nextPage() {
    if (pageCounter < 3) {
      setPage(pageCounter + 1);
      console.log(pageCounter);
    }
  }

  function prevPage() {
    if (pageCounter > 1) {
      setPage(pageCounter - 1);
      console.log(pageCounter);
    }
  }

  function printLog() {
    console.log(pageCounter);
  }

  return (
    <div id="options">
      <button onClick={prevPage} id="next">
        Back
      </button>
      <CardOption title={optionTitles.Option1} />
      <CardOption title={optionTitles.Option2} />
      <CardOption title={optionTitles.Option3} />
      <p>{pageCounter}</p>
      <button onClick={nextPage} id="next">
        Next
      </button>
      <button onClick={printLog} id="next">
        log
      </button>
    </div>
  );
}
function CardOption(props) {
  return (
    <div className="card">
      <h2>{props.title}</h2>
    </div>
  );
}

export default Options;
以下是组件代码:

从“React”导入React;
导入“/styles.css”;
从“React”导入React,{useState,useffect};
函数选项(){
//组成状态
常量[pageCounter,setPage]=使用状态(1);
常量[optionTitles,setOptionTitles]=useState({
选项1:“租赁结束清洁”,
选项2:“定期打扫房屋”,
选项3:“其他清洁”
});
//组成变量
常量页面标题={
选项1:“租赁结束清洁”,
选项2:“定期打扫房屋”,
选项3:“其他清洁”
};
常量pageTwoTitles={
选项1:“Blah1”,
选项2:“Blah12”,
选项3:“Blah13”
};
const pageThreeTitles={
选项1:“MrMagoo”,
选项2:“NIS”,
选项3:“波涛”
};
函数updatetiles(){
开关(分页计数器){
案例1:
setOptionTitles(pageOneTitles);
打破
案例2:
setOptionTitles(第二页标题);
打破
案例3:
setOptionTitles(第三页标题);
打破
违约:
console.log(“默认”);
打破
}
}
函数下一页(){
如果(分页计数器<3){
设置页面(页面计数器+1);
updatetiles();
控制台日志(分页计数器);
}
}
函数prevPage(){
如果(分页计数器>1){
设置页面(页面计数器-1);
updatetiles();
控制台日志(分页计数器);
}
}
函数printLog(){
控制台日志(分页计数器);
}
返回(
返回
{}

下一个 日志 ); } 功能卡选项(道具){ 返回( {props.title} ); } 导出默认选项;
下面是我尝试使用hook useffect的代码,但是我得到一个错误,说“超过了最大更新深度”

import React,{useState,useffect}来自“React”;
函数选项(){
//组成状态
常量[pageCounter,setPage]=使用状态(1);
常量[optionTitles,setOptionTitles]=useState({
选项1:“第1.11页”,
选项2:“定期打扫房屋”,
选项3:“其他清洁”
});
//组成变量
常量页面标题={
选项1:“第1.1页”,
选项2:“定期打扫房屋”,
选项3:“其他清洁”
};
常量pageTwoTitles={
选项1:“第2.1页”,
选项2:“Blah12”,
选项3:“Blah13”
};
const pageThreeTitles={
选项1:“第3.1页”,
选项2:“NIS”,
选项3:“波涛”
};
useffect(()=>{
开关(分页计数器){
案例1:
setOptionTitles(pageOneTitles);
打破
案例2:
setOptionTitles(第二页标题);
打破
案例3:
setOptionTitles(第三页标题);
打破
违约:
console.log(“默认”);
打破
}
},[pageCounter、pageOneTitles、pageTwoTitles、pageTwoTitles]);
函数下一页(){
如果(分页计数器<3){
设置页面(页面计数器+1);
控制台日志(分页计数器);
}
}
函数prevPage(){
如果(分页计数器>1){
设置页面(页面计数器-1);
控制台日志(分页计数器);
}
}
函数printLog(){
控制台日志(分页计数器);
}
返回(
返回
{pageCounter}

下一个 日志 ); } 功能卡选项(道具){ 返回( {props.title} ); } 导出默认选项;

下面是useEffect钩子的代码沙盒:

我认为这应该可以:

import React, { useState, useEffect } from "react";

function Options() {
  // Component States
  const [pageCounter, setPage] = useState(1);
  const [optionTitles, setOptionTitles] = useState({
    Option1: "End of Lease Clean",
    Option2: "Regular House Cleaning",
    Option3: "Other Clean"
  });
  //Component Variables
  const pageOneTitles = {
    Option1: "End of Lease Clean",
    Option2: "Regular House Cleaning",
    Option3: "Other Clean"
  };
  const pageTwoTitles = {
    Option1: "Blah1",
    Option2: "Blah12",
    Option3: "Blah13"
  };
  const pageThreeTitles = {
    Option1: "MrMagoo",
    Option2: "Nins",
    Option3: "Pottao"
  };

  function updateTitles() {
    switch (pageCounter) {
      case 1:
        setOptionTitles(pageOneTitles);
        break;
      case 2:
        setOptionTitles(pageTwoTitles);
        break;
      case 3:
        setOptionTitles(pageThreeTitles);
        break;
      default:
        console.log("default");
        break;
    }
  }

  function nextPage() {
    if (pageCounter < 3) {
      setPage(prev => prev + 1, updateTitles());
      console.log(pageCounter);
    }
  }

  function prevPage() {
    if (pageCounter > 1) {
      setPage(pageCounter - 1, updateTitles());
      console.log(pageCounter);
    }
  }

  function printLog() {
    console.log(pageCounter);
  }

  return (
    <div id="options">
      <button onClick={() => prevPage() } } id="next">
        Back
      </button>
      <CardOption title={optionTitles.Option1} />
      <CardOption title={optionTitles.Option2} />
      <CardOption title={optionTitles.Option3} />
      <p>{}</p>
      <button onClick={() => { nextPage() }} id="next">
        Next
      </button>
      <button onClick={() => { printLog() }} id="next">
        log
      </button>
    </div>
  );
}
function CardOption(props) {
  return (
    <div className="card">
      <h2>{props.title}</h2>
    </div>
  );
}

export default Options;
import React,{useState,useffect}来自“React”;
函数选项(){
//组成状态
常量[pageCounter,setPage]=使用状态(1);
常量[optionTitles,setOptionTitles]=useState({
选项1:“租赁结束清洁”,
选项2:“定期打扫房屋”,
选项3:“其他清洁”
});
//组成变量
常量页面标题={
选项1:“租赁结束清洁”,
选项2:“定期打扫房屋”,
选项3:“其他清洁”
};
常量pageTwoTitles={
选项1:“Blah1”,
选项2:“Blah12”,
选项3:“Blah13”
};
const pageThreeTitles={
选项1:“MrMagoo”,
选项2:“NIS”,
选项3:“波涛”
};
函数updatetiles(){
开关(分页计数器){
案例1:
setOptionTitles(pageOneTitles);
打破
案例2:
setOptionTitles(第二页标题);
打破
案例3:
setOptionTitles(第三页标题);
打破
违约:
console.log(“默认”);
打破
}
}
函数下一页(){
如果(分页计数器<3){
setPage(prev=>prev+1,updateTitles());
控制台日志(分页计数器);
}
}
函数prevPage(){
如果(分页计数器>1){
setPage(pageCounter-1,updateTitles());
控制台日志(分页计数器);
}
}
函数printLog(){
控制台日志(分页计数器);
}
返回(
prevPage()}}id=“下一步”>
返回
import React, { useState, useEffect } from "react";

function Options() {
  // Component States
  const [pageCounter, setPage] = useState(1);
  const [optionTitles, setOptionTitles] = useState({
    Option1: "End of Lease Clean",
    Option2: "Regular House Cleaning",
    Option3: "Other Clean"
  });
  //Component Variables
  const pageOneTitles = {
    Option1: "End of Lease Clean",
    Option2: "Regular House Cleaning",
    Option3: "Other Clean"
  };
  const pageTwoTitles = {
    Option1: "Blah1",
    Option2: "Blah12",
    Option3: "Blah13"
  };
  const pageThreeTitles = {
    Option1: "MrMagoo",
    Option2: "Nins",
    Option3: "Pottao"
  };

  function updateTitles() {
    switch (pageCounter) {
      case 1:
        setOptionTitles(pageOneTitles);
        break;
      case 2:
        setOptionTitles(pageTwoTitles);
        break;
      case 3:
        setOptionTitles(pageThreeTitles);
        break;
      default:
        console.log("default");
        break;
    }
  }

  function nextPage() {
    if (pageCounter < 3) {
      setPage(prev => prev + 1, updateTitles());
      console.log(pageCounter);
    }
  }

  function prevPage() {
    if (pageCounter > 1) {
      setPage(pageCounter - 1, updateTitles());
      console.log(pageCounter);
    }
  }

  function printLog() {
    console.log(pageCounter);
  }

  return (
    <div id="options">
      <button onClick={() => prevPage() } } id="next">
        Back
      </button>
      <CardOption title={optionTitles.Option1} />
      <CardOption title={optionTitles.Option2} />
      <CardOption title={optionTitles.Option3} />
      <p>{}</p>
      <button onClick={() => { nextPage() }} id="next">
        Next
      </button>
      <button onClick={() => { printLog() }} id="next">
        log
      </button>
    </div>
  );
}
function CardOption(props) {
  return (
    <div className="card">
      <h2>{props.title}</h2>
    </div>
  );
}

export default Options;
useEffect(()=> {
   // do stuff with pagecounter , which is updated count

},[pageCount])
useEffect(()=> {
   // do stuff with pagecounter , which is initial count

},[])
    const [pageCount, setPageCount] = useState(0)
    useEffect(()=> {
     if (pageCount===0){
       //this prevent to run on first render
       return 
     }
     // code here will only run on updating state
    },[pageCount])
  useEffect(()=> {
    updateTitles();

 },[pageCounter]);

  const updateTitles = useCallback(() => {
    switch (pageCounter) {
      case 1:
        setOptionTitles(pageOneTitles);
        break;
      case 2:
        setOptionTitles(pageTwoTitles);
        break;
      case 3:
        setOptionTitles(pageThreeTitles);
        break;
      default:
        console.log("default");
        break;
    }
  }, [pageCounter]);