我有两个组件
这两个组件显示在父文件中,它们以数组形式显示在html中的不同位置。
还在父文件中,有一个按钮创建 1 个输入和 1 个输出,它们相互交互且独立于其余部分。
到目前为止,主要问题是两个组件在渲染时显示了我需要的内容,但不改变值
家长
import InputTest from './InputTesting'
import TestOutput from './OutputTest'
const PageToCombine = () =>{
const [title, setTitle] = useState('qwrqw!')
const changeTitle = event => {
setTitle(event.target.value);
}
const [inputItems, setInputItems] = useState([
{id:32, type:"text", onchange:changeTitle, value:title},
])
const [outputItems, setOutputItems] = useState([
{id: 12, type:"text", value:title, onchange:changeTitle},
])
return(
<div>
{inputItems.map((inputitem) =>
<InputTest id={inputitem.id} type={inputitem.type} value={inputitem.value} onChange={inputitem.onchange}/>
)}
{outputItems.map(outputitem =>
<TestOutput id={outputitem.id} type={outputitem.type} value={outputitem.value} onChange={outputitem.onchange}/>
)}
</div>
)
}
测试输出组件
const TestOutput = (props) =>{
console.log(props)
return(
<div>
<h1 {...props} onChange = {props.onChange}>{props.value}</h1>
</div>
)
}
输入测试组件
const InputTest = (props) => {
console.log(props)
return(
<input className={classes.inputTestStyle} {...props}/>
)
}
解决这个问题的方向是正确的,关键是不要将预定义的
onChange
传递给输入,而是为每一项生成一个。因此,你的父母完全控制你的动态输入。
export default function App() {
const [inputs, setInputs] = useState([
{ id: 0, type: "text", value: "qwrqw!" }
]);
return (
<div>
<button
onClick={() => setInputs((p) => [...p, { id: p.length, value: "" }])}
>
New item
</button>
<div>
{inputs.map((input) => (
<Input
key={input.id}
onChange={(value) => {
setInputs((previous) =>
previous.map((p) =>
p.id === input.id ? { ...input, value } : p
)
);
}}
value={input.value}
/>
))}
</div>
<div>
{inputs.map((input) => (
<Output key={input.id} value={input.value} />
))}
</div>
</div>
);
}
function Input({ onChange, value }) {
return (
<div>
<input onChange={(e) => onChange(e.currentTarget.value)} value={value} />
</div>
);
}
function Output({ value }) {
return <h1>{value}</h1>;
}
请注意,
id
用于标识每个项目,这是 React 建议不要使用索引作为键,以防项目重新排序。这也意味着您可以自行生成唯一的 ID。
看起来您尝试使用多种状态,您可以只使用一种状态
const PageToCombine = () => {
const [items, setItems] = useState([
{
id: 32,
type: "text",
value: "inital value",
},
]);
return (
<div>
{items.map((inputitem) => (
<InputTest
id={inputitem.id}
type={inputitem.type}
value={inputitem.value}
onChange={(e) => {
// set the value of the item with the same id as the input
setItems((prevItems) => {
return prevItems.map((item) => {
if (item.id === inputitem.id) {
return { ...item, value: e.target.value };
}
return item;
});
});
}}
/>
))}
{items.map((outputitem) => (
<TestOutput
id="{outputitem.id}"
type="{outputitem.type}"
value="{outputitem.value}"
/>
))}
</div>
);
};
您使用了太多状态,并且似乎您没有通过设置 setInputItems 来更新 inputItems,您应该像这样只使用 inputTest 组件和 testOutput 组件的一种状态
父组件
import React, { useEffect, useState } from 'react'
import InputTest from './InputTest';
import TestOutput from './TestOutput ';
export default function PageToCombine() {
const [title, setTitle] = useState('qwrqw!')
const [inputItems, setInputItems] = useState([
{ id: 32, type: "text", value: title },
{ id: 33, type: "text", value: title },
])
const onchangeItems = (e, index) => {
let _inputItems = [...inputItems];
_inputItems[index].value = e.target.value
setInputItems(_inputItems)
}
return (
<div>
{inputItems.map((inputitem, index) =>
<>
<InputTest type={inputitem.type} value={inputitem.value} id=
{inputitem.id} onchange={(e) => onchangeItems(e, index)} />
<TestOutput type={inputitem.type} value={inputitem.value} id=
{inputitem.id} />
</>
)}
</div>
)
}
输入测试组件
export default function InputTest(props) {
return (
<input {...props} onChange={(e) => props.onchange(e,props.index)} />
)
}
输出测试组件
export default function TestOutput(props) {
return (
<div>
<h1 {...props}>{props.value}</h1>
</div>
)
}