我有一个状态,它是组件A中的一个数组。然后我有一个组件B(其道具是组件的状态),其中根据状态生成许多输入(类型文本) A.说3,然后我有3个输入类型的文本,它们包含在不同的组件和div中。我想知道我是否可以onChange
获取所有三个值并将其添加到组件A中的数组?订单无关紧要。也许有一些东西比如获取这个div容器的子代,然后将它们的所有值onChange
映射到一个数组中并设置状态?像这样的东西
编辑:
所以我写了这个,我可以看到名字是对的,但是我收到了这个错误:"警告:出于性能原因,这个合成事件会被重复使用。如果你看到这个,你正在访问已发布的财产目标...等等等等#34;。为什么我感觉我的setState不纯净。好的,我休息一下......
onMultipleChange(e) {
console.log(e.target.name);
this.setState((prevState, props) => {
let publicKeys = {...prevState.publicKeys, [e.target.name]: e.target.value};
return {...prevState, publicKeys}
}, console.log(this.state));
}
动态设置refs:
refSetter = (ix) => (ref) => { this._refs[ix] = ref; };
答案 0 :(得分:2)
警告:这是一种非常天真的做法,显然感觉很骇客,但仍然有效,并且是合法的。我确信有一种更好的方法并不依赖于refs
。
示例:https://codesandbox.io/s/002o3275jl
组件A
class ComponentA extends React.Component {
constructor(props) {
super(props);
this.state = {
vals: []
}
this._refs = {};
}
onChange = () => {
this.setState({
vals: Object
.keys(this._refs)
.map(key =>
this._refs[key] &&
this._refs[key].value
)
});
}
render() {
return (
<div>
All Vals: {this.state.vals.join(', ')}
<ComponentB _ref={ref => this._refs['b'] = ref} onChange={this.onChange} />
<ComponentC _ref={ref => this._refs['c'] = ref} onChange={this.onChange} />
<ComponentD _ref={ref => this._refs['d'] = ref} onChange={this.onChange} />
</div>
)
}
}
子组件
const ComponentB = ({_ref, onChange}) => (
<input ref={_ref} onChange={onChange} type="text" />
);
const ComponentC = ({ _ref, onChange }) => (
<input ref={_ref} onChange={onChange} type="text" />
);
const ComponentD = ({ _ref, onChange }) => (
<input ref={_ref} onChange={onChange} type="text" />
);
答案 1 :(得分:1)
我建立在@ lux的答案上(我的意思是我实际上采用了他的例子,并修改了它)并提出了一个不涉及refs的替代方案。
就在最近,我了解到React的SyntheticEvent(每次都重复使用)可以保留,这意味着它被从事件池中取出,即使其他事件发生,也可以保留引用被解雇。这就是我最终的结果:
class ComponentA extends React.Component {
constructor(props) {
super(props);
this.state = {
vals: [
{
name: "ComponentB",
value: ""
},
{
name: "ComponentC",
value: ""
},
{
name: "ComponentD",
value: ""
},
]
}
}
onChange = e => {
e.preventDefault();
e.persist();
this.handleMultipleChanges(e);
}
handleMultipleChanges = e => {
let currentInput = this.state.vals.find(val => val.name === e.target.name);
currentInput.value = e.target.value;
this.setState(prevState => ({
...prevState,
vals: prevState.vals.map(val => val.name === currentInput.name ? currentInput : val)
}));
}
render() {
return (
<div style={styles}>
AllVals: {this.state.vals.map(val => val.value).join(", ")}
<div><ComponentB name="ComponentB" onChange={this.onChange} /></div>
<div><ComponentC name="ComponentC" onChange={this.onChange} /></div>
<div><ComponentD name="ComponentD" onChange={this.onChange} /></div>
</div>
)
}
}
const ComponentB = ({name, onChange}) => (
<input name={name} onChange={onChange} type="text" />
);
const ComponentC = ({name, onChange }) => (
<input name={name} onChange={onChange} type="text" />
);
const ComponentD = ({name, onChange }) => (
<input name={name} onChange={onChange} type="text" />
);
修改强>
这是一个(非常基本的)变体,通过数字输入动态添加输入,因为这是OP的用例:
class ComponentA extends React.Component {
constructor(props) {
super(props);
this.state = {
inputNumber: 0,
vals: []
}
}
onChange = e => {
e.preventDefault();
e.persist();
this.handleMultipleChanges(e);
}
handleMultipleChanges = e => {
let currentInput = this.state.vals.find(val => val.name === e.target.name);
if (!currentInput) {
currentInput = {
name: e.target.name,
value: e.target.value
}
this.setState({vals: this.state.vals.concat(currentInput)});
} else {
currentInput.value = e.target.value;
this.setState(prevState => ({
...prevState,
vals: prevState.vals.map(val => val.name === currentInput.name ? currentInput : val)
}));
}
}
createInputs = e => {
const {inputNumber} = this.state;
const vals = [];
for (let i = 0; i<inputNumber; i++) {
vals[i] = {name: "input"+i, value:""};
}
this.setState({vals});
}
render() {
return (
<div>
AllVals: {this.state.vals.map(val => val.value).join(", ")}
<div>
<input type="number" onChange={e => this.setState({inputNumber: e.target.value})} />
<button onClick={this.createInputs}>Make Inputs</button>
</div>
{this.state.vals.map(
val => <div><input name={val.name} value={val.value} onChange={this.onChange} /></div>
)}
</div>
)
}
}