You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React:渲染列表相似组件时如何避免输入状态共享

问题:React组件切换时输入框值同步的解决方法

我有一个CustomReactComponent类,内部维护着一组相似的React组件列表,会根据条件渲染列表中的单个组件。该组件包含<input/>标签,当用户修改其中一个输入框的值时,所有输入框都会同步显示相同的值。如何解决这个问题,让每个组件实例的输入框存储不同的值?

最小可复现代码

import {Component} from "react";

export default class CustomReactComponent extends Component {
    constructor(props) {
        super(props);
        this.state = {selected: 0};
        this.list = [<div><input/></div>, <div><input/></div>, <div><input/></div>, <div><input/></div>];
    }

    onSelect = (e) => {
        this.setState({selected: e.target.value});
    }

    render() {
        let Component = this.list[this.state.selected];
        return (
            <div>
                <select onChange={this.onSelect}>
                    <option value="0">0</option>
                    <option value="1">1</option>
                    <option value="2">2</option>
                    <option value="3">3</option>
                </select>
                <div>
                    State:{this.state.selected}: 
                    {Component}
                </div>
            </div>
        );
    }
}

编辑1

正如@asynts所指出的,我们可以为每个组件使用key属性,但key仅在渲染兄弟组件时起作用,由于这里只渲染单个组件,key无法发挥作用——它会在selected状态改变时重新初始化组件。不过这是一个起点,至少不会将list中的所有组件视为同一对象。

编辑2:解决方案

经过调试和试验,我找到了一个解决方案:创建一个Wrap组件,将唯一id(uid)作为prop传入。渲染时,如果selected状态指向Wrap的uid,则设置其样式为display: initial,否则设置为display: none。此时key属性就派上用场了——我们可以始终渲染所有兄弟组件,并将key设置为与uid相同。

解决方案代码

import {Component} from "react";

function Wrap({uid}) {
    return <div>uid = {uid} : <input/></div>
}

export default class CustomReactComponent extends Component {
    constructor(props) {
        super(props);
        this.state = {selected: 0};
        this.list = [
            <Wrap uid={0}/>,
            <Wrap uid={1}/>,
            <Wrap uid={2}/>,
            <Wrap uid={3}/>
        ];
    }

    onSelect = (e) => {
        this.setState({selected: parseInt(e.target.value)});
    }

    render() {
        return (
            <div>
                State:
                <select onChange={this.onSelect}>
                    <option value="0">0</option>
                    <option value="1">1</option>
                    <option value="2">2</option>
                    <option value="3">3</option>
                </select>
                <div>
                    {this.list.map((component) =>
                        <div key={component.props.uid}
                             style={{display: component.props.uid !== this.state.selected ? 'none' : 'initial'}}>
                            {component}
                        </div>)}
                </div>
            </div>
        );
    }
}

内容的提问来源于stack exchange,提问作者Amith M

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 17:09:32