React上传 – 传递了不正确的属性

huangapple go评论61阅读模式
英文:

React uploading - incorrect properties are passed

问题

I am trying to pass properties to component and in which to upload file for right user.
Here is sandbox example:

我正在尝试将属性传递给组件,并在其中为正确的用户上传文件。以下是示例代码链接:

https://codesandbox.io/s/divine-moon-mj5w6n?file=/src/Main.tsx

As you can see I have dummy data:

正如您所见,我有虚拟数据:

export default [
  {
    id: "1",
    name: "John Doe",
    avatar: "app.png"
  },
  {
    id: "2",
    name: "Anna Doe",
    avatar: "pic.png"
  },
  {
    id: "3",
    name: "Michael Doe",
    avatar: "mypic.png"
  }
];

In my Main component I load CustomDataGrid component in which I am passing in one of its columns UploadAvatar component:

在我的主组件中,我加载CustomDataGrid组件,其中我在其中一个列中传递UploadAvatar组件:

{
    field: "avatar",
    headerName: "Аватар",
    headerClassName: "home-header",
    editable: false,
    align: "center",
    headerAlign: "center",
    renderCell: (params) => (
      <UploadAvatar
        avatar={params.value}
        name={params.row.name}
        userId={params.row.id}
      />
    )
  }

The problem is the following as you can test:

问题如下,您可以进行测试:

1. Click avatar of the third Person Michael Doe
The console.log from this row:

1. 单击第三个人Michael Doe的头像
从这一行的console.log中:

onClick={() => {
    console.log(userId);
    document.getElementById("avatar-input")!.click();
}}

Gives correct passed parameters:

给出了正确的传递参数:

mypic.png Michael Doe 3

2. After choosing file, the console.log() from uploadAvatar function:

2. 选择文件后,从uploadAvatar函数的console.log()中:

const uploadAvatar = (e: any) => {
    const file = e.target.files[0];
    if (!file) return;
    console.log(avatar, name, userId);
};

Gives parameters:

给出的参数:

app.png John Doe 1

Which are parameters the first user of the list, not the passed one. This is very strange for me and why I am having exactly the parameters I want in the first console.log but suddenly when I go in my uploadAvatar function I have different? How can I fix this behavior?

这些参数是列表中的第一个用户的参数,而不是传递的参数。这对我来说非常奇怪,为什么我在第一个console.log中正好有我想要的参数,但突然当我进入我的uploadAvatar函数时,参数却不同?我该如何修复这个行为?

EDIT 1:

I am pasting Upload Component as you wanted:

我将Upload组件粘贴如您所要求:

import React from "react";
import Avatar from "@mui/material/Avatar";

const UploadAvatar = ({
  avatar,
  name,
  userId
}: {
  avatar: string;
  name: string;
  userId: string;
}) => {
  const uploadAvatar = (e: any) => {
    const file = e.target.files[0];
    if (!file) return;
    console.log(avatar, name, userId);
  };
  return (
    <div>
      {avatar ? (
        <Avatar
          role="button"
          tabIndex={0}
          sx={{
            marginLeft: "-10px",
            marginRight: "10px",
            "&:hover": { cursor: "pointer" }
          }}
          alt="avatar"
          //src={`${shareServer}/avatars/${avatar}`}
          onClick={() => {
            console.log(avatar, name, userId);
            document.getElementById("avatar-input")!.click();
          }}
        ></Avatar>
      ) : (
        <Avatar
          role="button"
          tabIndex={0}
          sx={{
            marginLeft: "-10px",
            marginRight: "10px",
            "&:hover": { cursor: "pointer" }
          }}
          alt="avatar"
          src=""
          onClick={() => {
            document.getElementById("avatar-input")!.click();
          }}
        >
          {name
            ? name
                .split(/\s/)
                .reduce(
                  (response: any, word: any) => (response += word.slice(0, 1)),
                  ""
                )
            : ""
          }
        </Avatar>
      )}
      <input
        id="avatar-input"
        type="file"
        onChange={uploadAvatar}
        style={{ display: "none", position: "absolute" }}
        accept="image/*"
      />
    </div>
  );
};

export default UploadAvatar;

Please note that the code contains HTML and JavaScript, and the HTML tags have not been translated.

英文:

I am trying to pass properties to component and in which to upload file for right user.
Here is sandbox example:

https://codesandbox.io/s/divine-moon-mj5w6n?file=/src/Main.tsx

As you can see I have dummy data:

export default [
{
id: &quot;1&quot;,
name: &quot;John Doe&quot;,
avatar: &quot;app.png&quot;
},
{
id: &quot;2&quot;,
name: &quot;Anna Doe&quot;,
avatar: &quot;pic.png&quot;
},
{
id: &quot;3&quot;,
name: &quot;Michael Doe&quot;,
avatar: &quot;mypic.png&quot;
}
];

In my Main component I load CustomDataGrid component in which I am passing in one of its columns UploadAvatar component:

{
field: &quot;avatar&quot;,
headerName: &quot;Аватар&quot;,
headerClassName: &quot;home-header&quot;,
editable: false,
align: &quot;center&quot;,
headerAlign: &quot;center&quot;,
renderCell: (params) =&gt; (
&lt;UploadAvatar
avatar={params.value}
name={params.row.name}
userId={params.row.id}
/&gt;
)
},

The problem is the following as you can test:

1. Click avatar of the third Person Michael Doe
The console.log from this row:

    onClick={() =&gt; {
console.log(userId);
document.getElementById(&quot;avatar-input&quot;)!.click();
}}

Gives correct passed parameters:
mypic.png Michael Doe 3

2. After choosing file, the console.log() from uploadAvatar function:

const uploadAvatar = (e: any) =&gt; {
const file = e.target.files[0];
if (!file) return;
console.log(avatar, name, userId);
};

Gives parameters:

> app.png John Doe 1

Which are parameters the first user of the list, not the passed one. This is very strange for me and why I am having exactly the parameters I want in first console.log but suddenly when go in my uploadAvatar function I have different? How can I fix this behavior?

EDIT 1:

I am pasting Upload Component as you wanted:

import React from &quot;react&quot;;
import Avatar from &quot;@mui/material/Avatar&quot;;
const UploadAvatar = ({
avatar,
name,
userId
}: {
avatar: string;
name: string;
userId: string;
}) =&gt; {
const uploadAvatar = (e: any) =&gt; {
const file = e.target.files[0];
if (!file) return;
console.log(avatar, name, userId);
};
return (
&lt;div&gt;
{avatar ? (
&lt;Avatar
role=&quot;button&quot;
tabIndex={0}
sx={{
marginLeft: &quot;-10px&quot;,
marginRight: &quot;10px&quot;,
&quot;&amp;:hover&quot;: { cursor: &quot;pointer&quot; }
}}
alt=&quot;avatar&quot;
//src={`${shareServer}/avatars/${avatar}`}
onClick={() =&gt; {
console.log(avatar, name, userId);
document.getElementById(&quot;avatar-input&quot;)!.click();
}}
&gt;&lt;/Avatar&gt;
) : (
&lt;Avatar
role=&quot;button&quot;
tabIndex={0}
sx={{
marginLeft: &quot;-10px&quot;,
marginRight: &quot;10px&quot;,
&quot;&amp;:hover&quot;: { cursor: &quot;pointer&quot; }
}}
alt=&quot;avatar&quot;
src=&quot;&quot;
onClick={() =&gt; {
document.getElementById(&quot;avatar-input&quot;)!.click();
}}
&gt;
{name
? name
.split(/\s/)
.reduce(
(response: any, word: any) =&gt; (response += word.slice(0, 1)),
&quot;&quot;
)
: &quot;&quot;}
&lt;/Avatar&gt;
)}
&lt;input
id=&quot;avatar-input&quot;
type=&quot;file&quot;
onChange={uploadAvatar}
style={{ display: &quot;none&quot;, position: &quot;absolute&quot; }}
accept=&quot;image/*&quot;
/&gt;
&lt;/div&gt;
);
};
export default UploadAvatar;

答案1

得分: 1

设置文件输入的唯一标识:

      <input
        id={name}
        type="file"
        onChange={uploadAvatar}
        style={{ display: "none", position: "absolute" }}
        accept="image/*"
      />
        <Avatar
          role="button"
          tabIndex={0}
          sx={{
            marginLeft: "-10px",
            marginRight: "10px",
            "&:hover": { cursor: "pointer" }
          }}
          alt="avatar"
          //src={`${shareServer}/avatars/${avatar}`}
          onClick={() => {
            document.getElementById(name).click();
          }}
        />

使用 ref 访问 DOM 元素:

const ref = useRef();

//...

     <input
        ref={ref}
        id={name}
        type="file"
        onChange={uploadAvatar}
        style={{ display: "none", position: "absolute" }}
        accept="image/*"
      />

//...

ref.current.click()

使用 ref 不会出现唯一标识的问题。

英文:

Set unique id for file input:

      &lt;input
id={name}
type=&quot;file&quot;
onChange={uploadAvatar}
style={{ display: &quot;none&quot;, position: &quot;absolute&quot; }}
accept=&quot;image/*&quot;
/&gt;
        &lt;Avatar
role=&quot;button&quot;
tabIndex={0}
sx={{
marginLeft: &quot;-10px&quot;,
marginRight: &quot;10px&quot;,
&quot;&amp;:hover&quot;: { cursor: &quot;pointer&quot; }
}}
alt=&quot;avatar&quot;
//src={`${shareServer}/avatars/${avatar}`}
onClick={() =&gt; {
document.getElementById(name).click();
}}
/&gt;

And use ref for access DOM elements.

NOT:

document.getElementById(name).click();

With refs:

ref = useRef()
//...
&lt;input
ref={ref}
id={name}
type=&quot;file&quot;
onChange={uploadAvatar}
style={{ display: &quot;none&quot;, position: &quot;absolute&quot; }}
accept=&quot;image/*&quot;
/&gt;
//...
ref.current.click()

With ref wouldn't be a problem with not unique id.

https://codesandbox.io/s/gallant-williamson-eqx82b?file=/src/component/UploadAvatar.tsx

huangapple
  • 本文由 发表于 2023年2月16日 18:23:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/75470852.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定