【问题标题】:React hook changing the state variable of wrong component when file input文件输入时反应钩子改变错误组件的状态变量
【发布时间】:2021-09-14 15:12:34
【问题描述】:

代码沙盒:https://codesandbox.io/s/vigilant-elgamal-dciqs

当我输入图像并尝试在同一个容器上显示其预览时,只有第一个容器中的图像会更新,即 setImage 仅更改第一个组件的 photo 值。我该如何解决这个问题?

App.js

import { useState } from "react";
import "./styles.css";
import InputContainer from './InputContainer'
export default function App() {
const [inputArr,setInputArr] = useState([])
const addInputContainer=()=>{
setInputArr([...inputArr,''])
}
return (
 <div className="App">
  <button onClick={addInputContainer}>Add Input-Container</button><br/>
  {inputArr.map((input,index)=>{
    return <InputContainer key={index}/>
  })}
  
 </div>
 ); 
}

InputContainer.jsx

import { useState } from "react";

const InputContainer = () => {
  const [image, setImage] = useState("");
  const handleClick = () => {
    document.querySelector(".input-image").click();
  };
  const handleInput = (e) => {
    const selected = e.target.files[0];
    if (!selected) return;
    let reader = new FileReader();
    reader.readAsDataURL(selected);

    reader.onload = () => {
      setImage(reader.result);
    };
  };
  return (
    <div className="input-container" onClick={handleClick}>
      {image ? <img src={image} className="image" /> : "Click For input"}
      <input
        type="file"
        onChange={handleInput}
        className="input-image"
        style={{ display: "none" }}
      />
    </div>
  );
};
export default InputContainer;

【问题讨论】:

    标签: javascript html reactjs react-hooks


    【解决方案1】:

    所有组件都有相同的固定类名"input-image"。当您在图像单击时使用类名进行查询时,它会采用第一个并在那里更新图像。

    我已经修改了你的代码,在沙箱中尝试过 - https://codesandbox.io/s/charming-cdn-vh5xv

    我向 InputContainer 传递了 1 个额外的道具,这个道具是动态的,获取数组的索引。然后我在输入标签的 id 字段中使用并使用这个 id 查询document.querySelector(`#${imgName}`).click();

    App.js

    import { useState } from "react";
    import "./styles.css";
    import InputContainer from "./InputContainer";
    export default function App() {
      const [inputArr, setInputArr] = useState([]);
      const addInputContainer = () => {
        setInputArr([...inputArr, ""]);
      };
      return (
        <div className="App">
          <button onClick={addInputContainer}>Add Input-Container</button>
          <br />
          {inputArr.map((input, index) => {
            return <InputContainer key={index} imgName={`img-${index}`} />;
          })}
        </div>
      );
    }
    

    InputContainer.jsx

    import { useState } from "react";
    
    const InputContainer = ({ imgName }) => {
      const [image, setImage] = useState("");
      const handleClick = () => {
        document.querySelector(`#${imgName}`).click();
      };
      const handleInput = (e) => {
        const selected = e.target.files[0];
        if (!selected) return;
        let reader = new FileReader();
        reader.readAsDataURL(selected);
    
        reader.onload = () => {
          setImage(reader.result);
        };
      };
      return (
        <div className="input-container" onClick={handleClick}>
          {image ? <img src={image} className="image" /> : "Click For input"}
          <input
            type="file"
            onChange={handleInput}
            className="input-image"
            id={imgName}
            style={{ display: "none" }}
          />
        </div>
      );
    };
    export default InputContainer;
    

    【讨论】:

    • 这是正确答案。如果你有一个,也许你可以添加一个到代码框的链接:)
    猜你喜欢
    • 2022-07-11
    • 2019-09-17
    • 2020-04-26
    • 2020-05-18
    • 1970-01-01
    • 2020-01-26
    • 2021-05-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多