I am in position where I need to upload files to a particular channel but whats happening is , it's always uploaded to 1st tab/channel.
I am trying to use useRef to achieve it but don't know exactly what is missing ?
By tab I mean material-ui tabs
Consider values of tab as 0 ,1 and 2 respectively.
I'v tried to replicate the same in codesandbox here
Issue
try to add any image by clicking attach icon in tab 2 or 3 , it will be shown in tab 1.
const fileRef = useRef(tab); // tab value can be 0,1 or 2
useEffect(() => {
setProgress(0);
}, [file]);
const [handleSubmit, loading] = usePromise(() =>
onSend(text, fileKey).then(
() => {
setText('');
setFile();
setProgress(0);
setFileKey();
},
(e) => snack.error(e.message),
),
);
const onFileSelect = (e) => {
const { files } = e.target;
const f = files[0];
setFile(f);
fileRef.current.value = '';
const key = uuidv4() + '_' + f.name;
setUploading(true);
Storage.put(key, f, {
progressCallback: (progress) => {
const pc = (progress.loaded / progress.total) * 100;
setProgress(`Uploading... ${Math.round(pc)}%`);
},
})
.then((result) => {
setFileKey(result.key);
setUploading(false);
})
.catch((err) => {
setUploading(false);
snack.error(err.message);
});
};
return (
<div className={classes.root}>
{file && (
<FilePreview
loading={uploading}
progress={progress}
file={file}
onDelete={onDeleteFile}
/>
)}
<div className={classes.inputContainer}>
<div className={classes.actions}>
<div className={classes.upload}>
<IconButton component="label" htmlFor="file-input">
<AttachFileIcon />
</IconButton>
<input
accept={FILE_TYPES}
ref={fileRef}
id="file-input"
type="file"
onChange={onFileSelect}
/>
</div>
<IconButton
color="primary"
disabled={loading || uploading || !(text || fileKey)}
onClick={handleSubmit}
>
<SendIcon />
</IconButton>
</div>
</div>
</div>
The issue with your code is on this particular area:
<IconButton component="label" htmlFor="file-input">
<AttachFileIcon />
</IconButton>
<input
accept={FILE_TYPES}
ref={fileRef}
id="file-input"
type="file"
onChange={onFileSelect}
/>
Definition of for
(or htmlFor
in React)
The id of a labelable form-related element in the same document as the element. The first element in the document with an id matching the value of the for attribute is the labeled control for this label element, if it is a labelable element. If it is not labelable then the for attribute has no effect. If there are other elements which also match the id value, later in the document, they are not considered.
So in short, since all of the label
are pointing to the same id
, it will be correlated with the first instance of that input
field which is the 1 on the first tab.
To fix this, simply pass different htmlFor
& id
for each tab specific components
<IconButton component="label" htmlFor={tab}> <-- where tab should be unique to this tab
<AttachFileIcon />
</IconButton>
<input
accept={FILE_TYPES}
ref={fileRef}
id={tab} <-- where tab should be unique to this tab
type="file"
onChange={onFileSelect}
/>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.