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

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

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:

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

  1. export default [
  2. {
  3. id: "1",
  4. name: "John Doe",
  5. avatar: "app.png"
  6. },
  7. {
  8. id: "2",
  9. name: "Anna Doe",
  10. avatar: "pic.png"
  11. },
  12. {
  13. id: "3",
  14. name: "Michael Doe",
  15. avatar: "mypic.png"
  16. }
  17. ];

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

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

  1. {
  2. field: "avatar",
  3. headerName: "Аватар",
  4. headerClassName: "home-header",
  5. editable: false,
  6. align: "center",
  7. headerAlign: "center",
  8. renderCell: (params) => (
  9. <UploadAvatar
  10. avatar={params.value}
  11. name={params.row.name}
  12. userId={params.row.id}
  13. />
  14. )
  15. }

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中:

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

Gives correct passed parameters:

给出了正确的传递参数:

mypic.png Michael Doe 3

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

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

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

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组件粘贴如您所要求:

  1. import React from "react";
  2. import Avatar from "@mui/material/Avatar";
  3. const UploadAvatar = ({
  4. avatar,
  5. name,
  6. userId
  7. }: {
  8. avatar: string;
  9. name: string;
  10. userId: string;
  11. }) => {
  12. const uploadAvatar = (e: any) => {
  13. const file = e.target.files[0];
  14. if (!file) return;
  15. console.log(avatar, name, userId);
  16. };
  17. return (
  18. <div>
  19. {avatar ? (
  20. <Avatar
  21. role="button"
  22. tabIndex={0}
  23. sx={{
  24. marginLeft: "-10px",
  25. marginRight: "10px",
  26. "&:hover": { cursor: "pointer" }
  27. }}
  28. alt="avatar"
  29. //src={`${shareServer}/avatars/${avatar}`}
  30. onClick={() => {
  31. console.log(avatar, name, userId);
  32. document.getElementById("avatar-input")!.click();
  33. }}
  34. ></Avatar>
  35. ) : (
  36. <Avatar
  37. role="button"
  38. tabIndex={0}
  39. sx={{
  40. marginLeft: "-10px",
  41. marginRight: "10px",
  42. "&:hover": { cursor: "pointer" }
  43. }}
  44. alt="avatar"
  45. src=""
  46. onClick={() => {
  47. document.getElementById("avatar-input")!.click();
  48. }}
  49. >
  50. {name
  51. ? name
  52. .split(/\s/)
  53. .reduce(
  54. (response: any, word: any) => (response += word.slice(0, 1)),
  55. ""
  56. )
  57. : ""
  58. }
  59. </Avatar>
  60. )}
  61. <input
  62. id="avatar-input"
  63. type="file"
  64. onChange={uploadAvatar}
  65. style={{ display: "none", position: "absolute" }}
  66. accept="image/*"
  67. />
  68. </div>
  69. );
  70. };
  71. 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:

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

As you can see I have dummy data:

  1. export default [
  2. {
  3. id: &quot;1&quot;,
  4. name: &quot;John Doe&quot;,
  5. avatar: &quot;app.png&quot;
  6. },
  7. {
  8. id: &quot;2&quot;,
  9. name: &quot;Anna Doe&quot;,
  10. avatar: &quot;pic.png&quot;
  11. },
  12. {
  13. id: &quot;3&quot;,
  14. name: &quot;Michael Doe&quot;,
  15. avatar: &quot;mypic.png&quot;
  16. }
  17. ];

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

  1. {
  2. field: &quot;avatar&quot;,
  3. headerName: &quot;Аватар&quot;,
  4. headerClassName: &quot;home-header&quot;,
  5. editable: false,
  6. align: &quot;center&quot;,
  7. headerAlign: &quot;center&quot;,
  8. renderCell: (params) =&gt; (
  9. &lt;UploadAvatar
  10. avatar={params.value}
  11. name={params.row.name}
  12. userId={params.row.id}
  13. /&gt;
  14. )
  15. },

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. onClick={() =&gt; {
  2. console.log(userId);
  3. document.getElementById(&quot;avatar-input&quot;)!.click();
  4. }}

Gives correct passed parameters:
mypic.png Michael Doe 3

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

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

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:

  1. import React from &quot;react&quot;;
  2. import Avatar from &quot;@mui/material/Avatar&quot;;
  3. const UploadAvatar = ({
  4. avatar,
  5. name,
  6. userId
  7. }: {
  8. avatar: string;
  9. name: string;
  10. userId: string;
  11. }) =&gt; {
  12. const uploadAvatar = (e: any) =&gt; {
  13. const file = e.target.files[0];
  14. if (!file) return;
  15. console.log(avatar, name, userId);
  16. };
  17. return (
  18. &lt;div&gt;
  19. {avatar ? (
  20. &lt;Avatar
  21. role=&quot;button&quot;
  22. tabIndex={0}
  23. sx={{
  24. marginLeft: &quot;-10px&quot;,
  25. marginRight: &quot;10px&quot;,
  26. &quot;&amp;:hover&quot;: { cursor: &quot;pointer&quot; }
  27. }}
  28. alt=&quot;avatar&quot;
  29. //src={`${shareServer}/avatars/${avatar}`}
  30. onClick={() =&gt; {
  31. console.log(avatar, name, userId);
  32. document.getElementById(&quot;avatar-input&quot;)!.click();
  33. }}
  34. &gt;&lt;/Avatar&gt;
  35. ) : (
  36. &lt;Avatar
  37. role=&quot;button&quot;
  38. tabIndex={0}
  39. sx={{
  40. marginLeft: &quot;-10px&quot;,
  41. marginRight: &quot;10px&quot;,
  42. &quot;&amp;:hover&quot;: { cursor: &quot;pointer&quot; }
  43. }}
  44. alt=&quot;avatar&quot;
  45. src=&quot;&quot;
  46. onClick={() =&gt; {
  47. document.getElementById(&quot;avatar-input&quot;)!.click();
  48. }}
  49. &gt;
  50. {name
  51. ? name
  52. .split(/\s/)
  53. .reduce(
  54. (response: any, word: any) =&gt; (response += word.slice(0, 1)),
  55. &quot;&quot;
  56. )
  57. : &quot;&quot;}
  58. &lt;/Avatar&gt;
  59. )}
  60. &lt;input
  61. id=&quot;avatar-input&quot;
  62. type=&quot;file&quot;
  63. onChange={uploadAvatar}
  64. style={{ display: &quot;none&quot;, position: &quot;absolute&quot; }}
  65. accept=&quot;image/*&quot;
  66. /&gt;
  67. &lt;/div&gt;
  68. );
  69. };
  70. export default UploadAvatar;

答案1

得分: 1

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

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

使用 ref 访问 DOM 元素:

  1. const ref = useRef();
  2. //...
  3. <input
  4. ref={ref}
  5. id={name}
  6. type="file"
  7. onChange={uploadAvatar}
  8. style={{ display: "none", position: "absolute" }}
  9. accept="image/*"
  10. />
  11. //...
  12. ref.current.click()

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

英文:

Set unique id for file input:

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

And use ref for access DOM elements.

NOT:

  1. document.getElementById(name).click();

With refs:

  1. ref = useRef()
  2. //...
  3. &lt;input
  4. ref={ref}
  5. id={name}
  6. type=&quot;file&quot;
  7. onChange={uploadAvatar}
  8. style={{ display: &quot;none&quot;, position: &quot;absolute&quot; }}
  9. accept=&quot;image/*&quot;
  10. /&gt;
  11. //...
  12. 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:

确定