Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sibling Components With Internal States are Re-Rendering Each Other #12918

Open
churbis opened this issue Jan 30, 2025 · 0 comments
Open

Sibling Components With Internal States are Re-Rendering Each Other #12918

churbis opened this issue Jan 30, 2025 · 0 comments
Labels

Comments

@churbis
Copy link

churbis commented Jan 30, 2025

I'm using React Router as a...

framework

Reproduction

  1. Create a route with components that have inputs with internal managed state (Playground.tsx below)
  2. Run in dev and load the route
  3. Edit the text in the non-managed (DOM value) input-- notice that all of the other sibling managed state components don't re-render
  4. Edit the text one of the the input components with internal managed state
  5. Observe that all of the sibling input components re-render using react dev tools

InputComponentRoute.tsx

import { useEffect, useRef, useState } from "react";
import ComponentInSeparateFile from "./TestExternalComponent";

export default function Playground() {
    return <div>
        <div>
            <input type="text" className="text-sm border border-gray-300 rounded-md p-2 cursor-text" placeholder="input text" />
        </div>
        <div>
            <InputWithState name="input 1" />
        </div>
        <div>
            <InputWithState name="input 2" />
        </div>
        <div>
            <MultiInputParentWithState />
        </div>
        <div>
            <ComponentInSeparateFile />
        </div>
    </div>;
}

function InputWithState(props: {name: string}) {
    const [value, setValue] = useState('');
    return <>
        <label htmlFor={props.name}>{props.name}</label>
        <input type="text" className="text-sm border border-gray-300 rounded-md p-2 cursor-text" placeholder="input text" value={value} onChange={(e) => setValue(e.target.value)} />
    </>;
}

function MultiInputParentWithState() {
    const [input1, setInput1] = useState('');
    const [input2, setInput2] = useState('');
    return <div>
        <input type="text" className="text-sm border border-gray-300 rounded-md p-2 cursor-text" placeholder="input text" value={input1} onChange={(e) => setInput1(e.target.value)} />
        <input type="text" className="text-sm border border-gray-300 rounded-md p-2 cursor-text" placeholder="input text" value={input2} onChange={(e) => setInput2(e.target.value)} />
    </div>;


}

TextExtnernalComponent.tsx

import { useState } from "react";

export default function ComponentInSeparateFile() {
    const [value, setValue] = useState('');
    return <div>
        <h1>Test External Component</h1>
        <input type="text" className="text-sm border border-gray-300 rounded-md p-2 cursor-text" placeholder="input text" value={value} onChange={(e) => setValue(e.target.value)} />
    </div>;
}

System Info

System:
    OS: Linux 5.15 Ubuntu 24.04.1 LTS 24.04.1 LTS (Noble Numbat)
    CPU: (12) x64 Intel(R) Core(TM) i7-8700K CPU @ 3.70GHz
    Memory: 6.33 GB / 15.59 GB
    Container: Yes
    Shell: 5.2.21 - /bin/bash
  Binaries:
    Node: 23.6.0 - ~/.nvm/versions/node/v23.6.0/bin/node
    npm: 10.9.2 - ~/.nvm/versions/node/v23.6.0/bin/npm

(this is WSL, I'm using Chrome latest on windows 10 to visit the page)

Used Package Manager

npm

Expected Behavior

Sibling components managing their own input state should not trigger re-renders on other component ancestor trees when the parent is not re-rendering. This makes it hard to debug your code.

Actual Behavior

Sibling components trigger re-renders on other components in the parent component.

@churbis churbis added the bug label Jan 30, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant