コード
- ページ表示コード
<Modal
visible={
isShowUploadModal} //弹框是否显示
onOk={
this.handleCloseModel} // 点击确定时的操作
onCancel={
this.handleCloseModel} //点击取消时的操作
title="文件上传"
// 关闭时销毁子元素,这个很有用,相当于关闭的时候结束了组件的生命周期
destroyOnClose={
true}
>
<Upload
ref={
this.modalRef} // 用到ref实现后面的弹框颜色控制
action={
apis.DeviceManagement} // 上传的地址
headers={
{
Authorization: token } // 可以在header里加上token
}
maxCount={
1} // 最大上传数量,控制为1
accept=".xls, .xlsx" //upload文件接收什么样的文件
beforeUpload={
this.handlerBeforeUpload} // 上传前的操作记录
onChange={
this.statusChange} //上传后的操作记录
>
<Button type="primary">
点击上传
</Button>
</Upload>
</Modal>
- イベント処理コード
// 文件上传的拦截
handlerBeforeUpload = (file, fileList) => {
const {
size } = file
if (size / 1024 / 1024 > 10) {
message.error("文件大小不能超过10兆")
return Upload.LIST_IGNORE
}
this.setState({
uploadLoading: true
})
return true
}
//onChange上传文件状态变化,有三个状态status:uploading done error。
//beforeUpload拦截的文件没有这些status
// 所以在onChange中将拦截的文件进行处理,一般来说,上传的文件要么走到error,
//要么走到done,进入error状态,代表接口报错了。走到done状态代表了上传成功状态。
statusChange = (res) => {
const {
file, fileList } = res
if (file.status == 'error') {
message.error(file?.response?.msg||"文件上传失败,请检查一下数据是否有错")
}
if (file.status == 'done') {
// 上传成功后重新获取数据
if (file.response.code === 100) {
// 通过ref将upload组件获取到后,调用上传失败的函数,实现在已经done后还能触
//发向error状态时的字体颜色为红色状态
this.modalRef.current.onError("文件上传失败", file.response, file)
}
if (file.response.code === 200) {
message.success(file.response?.msg || "文件上传成功")
// 上传成功后重新获取数据
// this.getDeviceList()
}
}
}
質問
- 知識ポイント
onChange アップロード ファイルのステータスの変更には、アップロード中、完了、エラーの 3 つのステータスがあります。
beforeUpload によってインターセプトされたファイルにはこれらのステータスがないため、インターセプトされたファイルは onChange で処理されます。一般的に、アップロードされたファイルはエラーになるか、完了してエラー状態に入ります。これは、インターフェイスがエラーを報告したことを意味します。完了状態になると、アップロードが成功した状態になります。 - 問題点
アップロードされたファイルは Excel ファイルであるため、バックエンドのドッキング インターフェイスから返されるステータス コードを使用してアップロードが成功したかどうかを判断し、バックエンドのプロンプト コードを表示します。したがって、この時点では完了に達しており、バックエンドから返されるステータスと応答を取得できます。ただし、後で問題になるのは、完了状態でアップロードが成功したかどうかを判断することです。失敗した場合は、アップロードされたファイルが次の図のように赤くなります。思いつく解決策は次のとおりです
。 - 1. 変数を使用して CSS 属性を制御する
ブラウザの要素検査を通じてアップロードに対応するクラス名を見つけて変更することはできますが、実装にはいくつかの問題があります。ただしこのように書くとdom要素を操作してスタイルの色を追加したり削除したりする可能性があり、reactの仮想dom設計に準拠していないので諦めます。 - 2.自身をアップロードすることで赤くなるイベント(onError)を発生させ、
reactのref属性で取得したい要素を取得することができます。ref を通じてアップロード属性を取得した後、 Onerror を呼び出しますthis.modalRef.current.onError("文件上传失败", file.response, file)
。file.response
これは、バックグラウンドから返されるデータ、file
つまりアップロードされたファイルです。
遭遇した穴
- シナリオ
アップロードはモーダル ポップアップ ボックスにネストされているため、ポップアップ ボックスをクリックして閉じると、アップロードされたファイルが破棄されるか、アップロード内の fileList がクリアされる必要があります。 - 問題
fileList を制御されたコンポーネントに変更した後、onChange イベントの状態が常にアップロード中になります。
<Upload
ref={
this.modalRef}
action={
apis.DeviceManagement}
headers={
{
Authorization: Token.token }
}
fileList={
fileList} // 将fileList变为受控组件
maxCount={
1}
accept=".xls, .xlsx"
beforeUpload={
this.handlerBeforeUpload}
onChange={
this.statusChange}
>
</Upload>
antd 公式 Web サイトを確認してください
。fileList が制御されている場合、リストにないファイルをアップロードしても、その後の onChange のステータス更新イベントがトリガーされないのはなぜですか?
onChange イベントはリスト内のファイルにのみ作用するため、fileList に対応するファイルがない場合、後続のイベントは無視されます。
- 解決策
最も簡単な解決策は、fileList がアップロード時に書き込まれず、依然として制御されていないことです。モーダルが閉じられると、そのサブコンポーネントは破棄されます。これはたまたまモーダルが ={true} でカプセル化されているだけでありdestroyOnClose
、ポップアップ ボックスを閉じるとコンポーネントが破棄される可能性があります。
destroyOnClose が閉じられたときにモーダルの子要素を破棄します