我有一个材料-ui LinearDeterminate进度条,我想传递的上传有多远。
const LinearDeterminate = ({ uploadPercentage, setuploadPercentage }) => {
const classes = useStyles();
const [uploadPercentage, setuploadPercentage] = useState("");
console.log(uploadPercentage);
return (
<div className={classes.root}>
<LinearProgress variant="determinate" value={uploadPercentage} />
</div>
);
};
...
<UploadInput
path={`customer_creatives/assets/${customer_id}/${new Date().getTime()}`}
onChange={(value) =>
updateFieldHandler("link_to_assets")({ target: { value } })
}
value={submissionData["link_to_assets"] || ""}
label="Link to Assets"
sublabel="*Zip files before uploading"
isImage={false}
/>
<LinearDeterminate />
...UploadInput是一个自定义的输入组件,它链接到DropZone (在那里进行上传)
import React, { useState } from "react";
import ReactDropzone from "react-dropzone";
import axios from "axios";
import { noop } from "lodash";
import HelpDialog from "components/HelpDialog";
import { API_URL } from "config";
const Dropzone = ({
path,
onChange = noop,
children,
multiple = false,
maxSize,
sizeHelper,
...props
}) => {
const [url, setUrl] = useState("");
const [loading, setLoading] = useState("");
const [uploadPercentage, setuploadPercentage] = useState("");
const [sizeHelperOpen, setSizeHelperOpen] = useState(false);
const onDrop = ([file]) => {
const contentType = file.type; // eg. image/jpeg or image/svg+xml
console.log(file);
if (maxSize && maxSize < file.size) {
setSizeHelperOpen(true);
return;
}
const generatePutUrl = `${API_URL}/generate-put-url`;
const generateGetUrl = `${API_URL}/generate-get-url`;
const options = {
onUploadProgress: (progressEvent) => {
//console.log("progressEvent.loaded " + progressEvent.loaded)
//console.log("progressEvent.total " + progressEvent.total)
let percent = Math.round(
(progressEvent.loaded / progressEvent.total) * 100
);
setuploadPercentage({
uploadPercentage: percent,
});
console.log(uploadPercentage);
},
params: {
Key: path,
ContentType: contentType,
},
headers: {
"Content-Type": contentType,
},
};
setUrl(URL.createObjectURL(file));
setLoading(true);
axios.get(generatePutUrl, options).then((res) => {
const {
data: { putURL },
} = res;
axios
.put(putURL, file, options)
.then(() => {
axios.get(generateGetUrl, options).then((res) => {
const { data: getURL } = res;
onChange(getURL);
setLoading(false);
});
})
.catch(() => {
setLoading(false);
});
});
};
return (
<ReactDropzone onDrop={onDrop} multiple={multiple} {...props}>
{({ getRootProps, getInputProps }) => (
<>
<div {...getRootProps()}>
<input {...getInputProps()} />
{children({ url, loading })}
</div>
<HelpDialog
open={sizeHelperOpen}
onClose={() => setSizeHelperOpen(false)}
>
{sizeHelper}
</HelpDialog>
</>
)}
</ReactDropzone>
);
};
export default Dropzone;我正在尝试将onUploadProgress函数的结果输入进度条。我能用定制的钩子吗?我的问题是Dropzone已经有了出口。谢谢你的建议!
发布于 2022-08-27 21:36:51
它看起来和提升国家地位一样简单。实际上,您已经在LinearDeterminate组件上拥有了LinearDeterminate道具。只需将该状态放在UploadInput和LinearDeterminate组件的公共父级中,然后继续将处理程序传递给DropZone组件。
从LinearDeterminate组件中删除状态
const LinearDeterminate = ({ uploadPercentage }) => {
const classes = useStyles();
return (
<div className={classes.root}>
<LinearProgress variant="determinate" value={uploadPercentage} />
</div>
);
};将其移动到公共父级
const [uploadPercentage, setuploadPercentage] = useState("");
...
<UploadInput
path={`customer_creatives/assets/${customer_id}/${new Date().getTime()}`}
onChange={(value) =>
updateFieldHandler("link_to_assets")({ target: { value } })
}
value={submissionData["link_to_assets"] || ""}
label="Link to Assets"
sublabel="*Zip files before uploading"
isImage={false}
setuploadPercentage={setuploadPercentage}
/>
<LinearDeterminate uploadPercentage={uploadPercentage}/>
...UploadInput组件
const UploadInput = ({ setuploadPercentage, ...allOtherCrazyProps }) => {
...
return (
<DropZone setuploadPercentage={setuploadPercentage} {...moreCrazyProps} />
);
};最后,在DropZone中
const Dropzone = ({
path,
onChange = noop,
children,
multiple = false,
maxSize,
sizeHelper,
setuploadPercentage, // this is the new prop
...props
}) => {
...
const options = {
onUploadProgress: (progressEvent) => {
...
setuploadPercentage(percent); // is a string?
console.log(uploadPercentage);
},
...
};
...
};如果您发现向下传递处理程序很麻烦,可以使用上下文来管理该状态,但是只要您使用UserInput,就需要将它包装在上下文提供程序上。
我还建议移动所有上传逻辑并构建类似于下移位-js的东西:一个钩子,它返回所有必要的道具,将一个元素转换为一个可下垂的上传器,但是您已经依赖于ReactDropzone组件,所以我认为,除非您尝试另一个模式https://blog.bitsrc.io/new-react-design-pattern-return-component-from-hooks-79215c3eac00,否则无法完成。
发布于 2022-08-26 21:46:36
您可以在每个axios成功调用之后设置上传优先级值。
axios.get(generatePutUrl, options).then(res => {
const {
data: { putURL }
} = res;
/* Set precent to 33% here */
axios
.put(putURL, file, options)
.then(() => {
/* Set precent to 66% */
axios.get(generateGetUrl, options).then(res => {
/* Set precent to 99% here */
const { data: getURL } = res;
onChange(getURL);
setLoading(false);
});
})
.catch(() => {
setLoading(false);
});
});希望这能有所帮助。
https://stackoverflow.com/questions/73475414
复制相似问题