REACT - 与父元素中的 onchange 输入(子)和输出(子)绑定

问题描述 投票:0回答:3

我有两个组件

  1. 输入 - 用户将在其中输入值
  2. 有一个输出(H1),该值将立即显示

这两个组件显示在父文件中,它们以数组形式显示在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}/>
    )
}
reactjs
3个回答
0
投票

解决这个问题的方向是正确的,关键是不要将预定义的

onChange
传递给输入,而是为每一项生成一个。因此,你的父母完全控制你的动态输入。

codesandbox 演示

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。


0
投票

看起来您尝试使用多种状态,您可以只使用一种状态

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>
  );
};

0
投票

您使用了太多状态,并且似乎您没有通过设置 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>
   )
}
 
© www.soinside.com 2019 - 2024. All rights reserved.