Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

137
Vistas
How to change child state from another child without re-rendering parent

I want to change the content of a child component in response to a user event in another child component without causing the parent to re-render.

I've tried storing the child state setter to a variable in the parent but it is not defined by the time the children have all rendered, so it doesn't work.

Is there a minimal way to accomplish this (without installing a state management library)?

ChildToChild.tsx

import React, {
  Dispatch,
  SetStateAction,
  useEffect,
  useRef,
  useState,
} from "react";

export default function ChildToChild() {
  const renderCounter = useRef(0);
  renderCounter.current = renderCounter.current + 1;

  let setChildOneContent;
  const childOneContentController = (
    setter: Dispatch<SetStateAction<string>>
  ) => {
    setChildOneContent = setter;
  };

  return (
    <div>
      <h1>Don't re-render me please</h1>
      <p>No. Renders: {renderCounter.current}</p>
      <ChildOne childOneContentController={childOneContentController} />
      <ChildTwo setChildOneContent={setChildOneContent} />
    </div>
  );
}

function ChildOne({
  childOneContentController,
}: {
  childOneContentController: (setter: Dispatch<SetStateAction<string>>) => void;
}) {
  const [content, setContent] = useState("original content");

  useEffect(() => {
    childOneContentController(setContent);
  }, [childOneContentController, setContent]);

  return (
    <div>
      <h2>Child One</h2>
      <p>{content}</p>
    </div>
  );
}

function ChildTwo({
  setChildOneContent,
}: {
  setChildOneContent: Dispatch<SetStateAction<string>> | undefined;
}) {
  return (
    <div>
      <h2>Child Two</h2>
      <button
        onClick={() => {
          if (setChildOneContent) setChildOneContent("content changed");
        }}
      >
        Change Child One Content
      </button>
    </div>
  );
}
about 4 years ago · Juan Pablo Isaza
3 Respuestas
Responde la pregunta

0

You should be able to achieve by

  1. Using state in child components
  2. Using a callback function in the parent component that calls the setState function of the child component. This will trigger re-render of the child but not of itself (parent).

Demo: https://codesandbox.io/s/child-re-rendering-only-x37ol

about 4 years ago · Juan Pablo Isaza Denunciar

0

For an one-off, you could use the following (another ref to store & use the ChildOne setContent:

import React, {
  Dispatch,
  SetStateAction,
  useEffect,
  useRef,
  useState
} from "react";

function ChildOne({
  setChildOneRef
}: {
  setChildOneRef: React.MutableRefObject<React.Dispatch<
    React.SetStateAction<string>
  > | null>;
}) {
  const [content, setContent] = useState("original content");

  useEffect(() => {
    setChildOneRef.current = setContent;
  }, [setChildOneRef]);

  return (
    <div>
      <h2>Child One</h2>
      <p>{content}</p>
    </div>
  );
}

function ChildTwo({
  setChildOneRef
}: {
  setChildOneRef: React.MutableRefObject<React.Dispatch<
    React.SetStateAction<string>
  > | null>;
}) {
  return (
    <div>
      <h2>Child Two</h2>
      <button
        onClick={() => {
          setChildOneRef.current?.("content changed");
        }}
      >
        Change Child One Content
      </button>
    </div>
  );
}

export function ChildToChild() {
  const renderCounter = useRef(0);
  renderCounter.current = renderCounter.current + 1;

  const setChildOneRef = useRef<Dispatch<SetStateAction<string>> | null>(null);
  return (
    <div>
      <h1>Don't re-render me please</h1>
      <p>No. Renders: {renderCounter.current}</p>
      <ChildOne setChildOneRef={setChildOneRef} />
      <ChildTwo setChildOneRef={setChildOneRef} />
    </div>
  );
}

If this pattern is common in your code, you may still want to use state management library or evaluate if "childs" should be really separated.

about 4 years ago · Juan Pablo Isaza Denunciar

0

You can create an object, store the hook on that object, and use the hook from the object on the children. Not sure why the output count increments twice...

import { useState } from "react";

let parentRenderCount = 0;
let child1RenderCount = 0;
let child2RenderCount = 0;

const Child1 = ( { stateHolder } ) => {
    const [count, setCount] = useState( 0 )
    console.log('child1 render', ++child1RenderCount)
    stateHolder.count = count
    stateHolder.setCount = setCount
    return <div>
        {count}
    </div>
}

const Child2 = ( { stateHolder } ) => {
    console.log('child2 render', ++child2RenderCount)
    return <button onClick={() => stateHolder.setCount( stateHolder.count + 1 )}>
        clickme
    </button>
}


function App() {
    const stateHolder = { }
    console.log('parent render', ++parentRenderCount)
    return (
        <div className="App">
            <Child1 stateHolder={stateHolder} />
            <Child2 stateHolder={stateHolder} />
        </div>
    );
}

export default App;
about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda