Reactjs useState从父级传递到子级,并在子级中使用';t触发子对象的重新渲染

Reactjs useState从父级传递到子级,并在子级中使用';t触发子对象的重新渲染,reactjs,components,rendering,next.js,use-state,Reactjs,Components,Rendering,Next.js,Use State,因此,我猜在更新useState时,父组件不会重新呈现子组件。 但是组件应该在使用useState时自动重新渲染,对吗? 或者我错过了什么 index.js import { useEffect, useState, useRef } from "react"; import Clicking from "./clicking"; export default function IndexPage() { const parentBtn = use

因此,我猜在更新useState时,父组件不会重新呈现子组件。 但是组件应该在使用useState时自动重新渲染,对吗? 或者我错过了什么

index.js

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

import Clicking from "./clicking";

export default function IndexPage() {
  const parentBtn = useRef(null);

  const [clicks, setClicks] = useState(0);

  useEffect(() => {
    console.log("Clicks: ", clicks);

    if (null !== parentBtn.current) {
      parentBtn.current.addEventListener("click", () => setClicks(clicks + 1));
    }
  }, [clicks]);

  return (
    <div>
      <p>Clicks number : {clicks}</p>
      <Clicking clicks={clicks} setClicks={setClicks} />
      <button ref={parentBtn}>Parent button</button>
    </div>
  );
}
import { useEffect, useRef } from "react";

const Clicking = ({ clicks, setClicks }) => {
  const childBtn = useRef(null);

  useEffect(() => {
    childBtn.current.addEventListener("click", () => setClicks(clicks + 1));
  }, []);

  return <button ref={childBtn}>Child button</button>;
};

export default Clicking;
从“react”导入{useffect,useState,useRef};
从“/单击”导入单击;
导出默认函数IndexPage(){
const parentBtn=useRef(null);
const[clicks,setClicks]=useState(0);
useffect(()=>{
日志(“点击:”,点击);
if(null!==parentBtn.current){
parentBtn.current.addEventListener(“单击“,()=>setClicks(单击+1));
}
},[点击];
返回(
点击次数:{Clicks}

父按钮 ); }
点击.js

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

import Clicking from "./clicking";

export default function IndexPage() {
  const parentBtn = useRef(null);

  const [clicks, setClicks] = useState(0);

  useEffect(() => {
    console.log("Clicks: ", clicks);

    if (null !== parentBtn.current) {
      parentBtn.current.addEventListener("click", () => setClicks(clicks + 1));
    }
  }, [clicks]);

  return (
    <div>
      <p>Clicks number : {clicks}</p>
      <Clicking clicks={clicks} setClicks={setClicks} />
      <button ref={parentBtn}>Parent button</button>
    </div>
  );
}
import { useEffect, useRef } from "react";

const Clicking = ({ clicks, setClicks }) => {
  const childBtn = useRef(null);

  useEffect(() => {
    childBtn.current.addEventListener("click", () => setClicks(clicks + 1));
  }, []);

  return <button ref={childBtn}>Child button</button>;
};

export default Clicking;
从“react”导入{useffect,useRef};
常量单击=({clicks,setClicks})=>{
const childBtn=useRef(null);
useffect(()=>{
childBtn.current.addEventListener(“单击“,()=>setClicks(单击+1));
}, []);
返回子按钮;
};
导出默认点击;
有人知道如何解决这个问题吗

下面是该案例的代码沙盒:


谢谢你的帮助

我在我使用
setClicks的child中找到了一个解决方案

我换了

setClicks(clicks + 1)

它是有效的。
也许有人对react生命周期或其他方面有解释?

问题是您的
useEffect
只运行一次,因此只接收
单击的初始值

您需要做的是停止将
clicks
值传递给子级,只需从
setClicks
函数获取状态值,因为您的更新仍然取决于以前的状态值

您还应该将
setClicks
作为依赖项传递给
useffect
,尽管在这种情况下,它在技术上不是强制性的,因为函数已被记忆,因此永远不会更改,但这是一种最佳做法,如果您这样做,您将在将来避免出现错误

但是,在您的情况下,子对象中的
useffect
无论如何都是无用的,您最好只需将
onClick
道具传递给子对象,该道具将在单击按钮时触发父对象函数更新计数器。
但是,对于父级来说也是如此,您可以简单地使用
onClick
prop而不是使用
useRef
,最终得到更简单的代码:

index.js

从“react”导入{useState};
从“/单击”导入单击;
导出默认函数IndexPage(){
const[clicks,setClicks]=useState(0);
常量updateClickCounter=()=>{
设置点击次数(点击次数=>点击次数+1);
};
返回(
点击次数:{Clicks}

父按钮 ); }
点击.js

const Clicking=({onClick})=>{
返回子按钮;
};
导出默认点击;

而不是将stae和setState传递给子级。将onClick事件冒泡到父对象我已经创建了一个示例代码-好的,谢谢@Valentin,所以现在它正确地更新了
单击
var,但是如果我想在子对象中显示
单击
var,我如何获得更新状态?现在,如果我将
clicks
传递给子级并记录它,它总是显示它的初始值。@Maël如果你将它作为道具传递,你只需在返回中用
{clicks}
显示它即可。如果要在
useffect
中使用该值,则需要将其作为参数传递,以便在每次参数更新
useffect(()=>{console.log(“clicks”,clicks)},[clicks]),
确定,我试图在useffect之外使用它,因此它与react不同步。非常感谢。