英文:
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: "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:
{
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:
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:
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 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 "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;
答案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:
<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();
}}
/>
And use ref for access DOM elements.
NOT:
document.getElementById(name).click();
With refs:
ref = useRef()
//...
<input
ref={ref}
id={name}
type="file"
onChange={uploadAvatar}
style={{ display: "none", position: "absolute" }}
accept="image/*"
/>
//...
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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论