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
相关产品推荐
相关产品推荐

