Ant-design: アップロードfile.statusは常にアップロードされています

作成日 2016年07月18日  ·  90コメント  ·  ソース: ant-design/ant-design

ローカル環境

  • antdバージョン:1.6.5
  • オペレーティングシステムとそのバージョン:mac 10.11.5
  • ブラウザとそのバージョン:50.0.2661.102

あなたは何をした?

バージョン1.6.5のUploadコントロールのonChangeメソッドは1回だけ実行され、info.file.statusは常にアップロードされ、http要求は正常であり、200が返されます。
1.6.4にダウングレードした後の通常の使用、info.file.statusはアップロード後に行われます

期待する結果は次のとおりです。

実結果:

再現可能なオンラインデモ

番号

Question Usage ❓FAQ

最も参考になるコメント

制御モードの場合、すべての状態がアップロードに同期されるように、常にonChangeにState fileList onChangeを設定する必要があります。ここでの表現に似ています: http: //ant.design/components/upload/#components -upload-demo-fileList

// good

onFileChange(fileList) {
  if ( ... ) {
    ...
  } else {
    ...
  }
  // always setState
  this.setState({ fileList: [...fileList] });
}

...

<Upload fileList={this.state.fileList} onChange={this.onFileChange} />
// bad

onFileChange(fileList) {
  if ( ... ) {
    this.setState({ fileList: [...fileList] });
  } else {
    ...
  }
}

...

<Upload fileList={this.state.fileList} onChange={this.onFileChange} />

制御されたコンポーネントの概念を研究することをお勧めします: https ://facebook.github.io/react/docs/forms.html#managed -components


Uploadが配列の変更を確実に感知できるようにするには、 fileListクローンを作成する必要があることに注意してください。

- this.setState({ fileList });
+ this.setState({ fileList: [...fileList] });

全てのコメント90件

私の実際のテストは問題ありませんが、簡単に再現できるように問題の完全なコードを提供するのは便利ですか?

制御モードの場合、すべての状態がアップロードに同期されるように、常にonChangeにState fileList onChangeを設定する必要があります。ここでの表現に似ています: http: //ant.design/components/upload/#components -upload-demo-fileList

// good

onFileChange(fileList) {
  if ( ... ) {
    ...
  } else {
    ...
  }
  // always setState
  this.setState({ fileList: [...fileList] });
}

...

<Upload fileList={this.state.fileList} onChange={this.onFileChange} />
// bad

onFileChange(fileList) {
  if ( ... ) {
    this.setState({ fileList: [...fileList] });
  } else {
    ...
  }
}

...

<Upload fileList={this.state.fileList} onChange={this.onFileChange} />

制御されたコンポーネントの概念を研究することをお勧めします: https ://facebook.github.io/react/docs/forms.html#managed -components


Uploadが配列の変更を確実に感知できるようにするには、 fileListクローンを作成する必要があることに注意してください。

- this.setState({ fileList });
+ this.setState({ fileList: [...fileList] });

e0a986ed71cd87e506fb8e4ee5e2e0130fc70ae1

Uploadコントロールを使用すると、常にアップロードに失敗し、常にエラーを報告するのはなぜですか:POST http:// localhost :8081 / api / nes / 2 / uploadMusic / r_ty 404(見つかりません)

制限されたURLにIDフィールドとトークンを追加する方法は?アクションを使用してそれらを転送する方法は? アクションはアドレスを与えるだけです、あなたはデータを追加できませんか?

React.PureComponentが最適化判断のレイヤーを作成したため、React.PureComponentにはまだ問題があります。ファイルリストには参照がキャッシュされています。同じオブジェクトの場合、更新されません。新しいオブジェクトは、React.PureComponentですぐに生成する必要があります。
handleChange =({fileList})=> {
//バグを修正
this.setState({fileList:fileList.slice()});
}

@ afc163

@yongningfuヒントをありがとう、それは更新されました。

特記事項:浅い比較にReact shouldComponentUpdateを使用する場合、制御モードでは、状態がUploadに同期されていても、更新されません。その理由は、参照が一致している===であるため、レンダリングが妨げられます

複数の画像をアップロードした後、beforeUploadがアップロード画像パラメータの制限を設定すると、onChangeは正常にアップロードされた画像のリストを取得します。いくつかの画像を正常にアップロードした後、間違った画像をアップロードすると、以前に正常にアップロードされたすべての画像がクリアされます。解決策はありますか? ?

コールバックするときは、this.setState({fileList});などのステータスをリセットする必要があります。

handleChange =(情報)=> {
console.log(info);

    //把fileList拿出来
    let {fileList} = info;

    const status = info.file.status;
    if (status !== 'uploading') {
        console.log(info.file, info.fileList);
    }
    if (status === 'done') {
        message.success(`${info.file.name} file uploaded successfully.`);
    } else if (status === 'error') {
        message.error(`${info.file.name} file upload failed.`);
    }

    //重新设置state
    this.setState( {fileList});
}

状態が変化する限り、onChangeは内部的に呼び出されますよね?

この問題は長い間解決されており、setStateであることが判明しました。コンポーネントはこのように設計されるべきではありません、なぜ怠惰な外部状態に依存するのですか?

base64コードのみが必要で、バックグラウンドと対話しません。バックグラウンドにリクエストを自動的に送信する問題を解決するにはどうすればよいですか?

このコンポーネントを維持するのは砂の彫刻ですか?

アップロードが失敗し、以前のデフォルトの画像を表示したい場合はどうすればよいですか?

アップロードに失敗しました。エラー処理機能で、
this.setState({
fileList:inital_list
})
前のデフォルトの画像を表示できます

コンポーネントのアップロードが完了したときのコールバック実行のタイミングに問題がある可能性があると思います。次の状況を考慮してください。

コンポーネント関係の疑似コード:

<Controller>
  <Upload fileList={controller.state.fileList} onUpload={controller.onUpload} />
</Controller>

親コンポーネントControllerは、 onUpload介して状態を更新するように通知されます。

ただし、Reactの状態更新は非同期であるため、画像のアップロードが十分に速い場合、実行順序は次のようになります。
constroller.onUpload(会调用 controller.setState) -> upload.onSuccess -> upload.componentWillReceiveProps
upload.onSuccess実行の場合、アップロード状態の対応するアップロード済みファイルはありません。アップロードのstate.fileList更新はcomponentWillReceiveProps依存するためです。

したがって、このコンポーネントの現在の制御モードは信頼できないと思います。

可能な解決策:

  1. 制御モードでは、 onSuccess実際の処理ロジックおよびその他のイベントによりcomponentDidUpdate実行されます
  2. state.fileList回避props.fileListに完全に依存し、コンポーネントインスタンスインスタンスのfileList(た状態を維持し、イベントアップロードの処理を容易にします

let {file、fileList} = info;
if(file.size / 1024/1024> 10){
戻る
}
console.log(file.status)
if(file.status!= "done"){
fileList = []
}
this.setState({
fileList、
}、console.log(
this.state.fileList、
this.props.form.getFieldValue( 'upload')
))
当我追加

{file、fileList} = info;とします。
if(file.size / 1024/1024> 10){
戻る
}
console.log(file.status)
if(file.status!= "done"){
fileList = []
}
this.setState({
fileList、
}、console.log(
this.state.fileList、
this.props.form.getFieldValue( 'upload')
))
追加すると
if(file.status!= "done"){
fileList = []
}
onchangeを一度監視し、削除するだけですが、それはなぜですか?

この問題は解決されていませんね

componentWillReceivePropsライフサイクル中にsetStateを呼び出して画像を表示しても、変更はありません。

componentWillReceiveProps = (nextProps) => {
    this.setState(() => ({ 
      fileList: [...nextProps.fileList] 
    }));
  }  
// ...
<Upload FileList={this.state.fileList} ...>
//...

@ afc163アップロードコンポーネントが複数のファイルをアップロードする場合、1つのファイルしか正常にアップロードできないとどうなりますか?ログからログを確認してください。info.fileListのステータスはアップロード中です。パーセンテージと応答はどちらも未定義ですが、httpリクエストは200です。助けてください

@PTGuanもちろん、このコンポーネントは1つずつアップロードされ、バックエンドAPIも1つずつファイルで受信されます。アップロードがバッチでアップロードに成功した後、コールバックでuploadを再帰的に呼び出す必要があります。あなたの質問を終わらせたいです。

この問題は解決されません+1

antd3.8 +にはまだstatus = 'loading'しかなく、完了状態はありません。どのように解決しますか?

常にアップロードするための公式の解決策はありますが、onSuccessは正しいhttp200応答を待つことができます

問題は解決しました、this.setState({fileList:[... fileList]});この文は非常に重要です。問題がある場合は、これに焦点を当ててください。

@EnixCoda 、あなたが説明した問題に遭遇したようですが、時々アップロードしますが、常に「アップロード中」と表示されます。

@withzhaoyuええと、実際、ここのほとんどの人はこの問題に直面しています。このコンポーネントは、React状態を通じてアップロードの進行状況を保存するのにあまり信頼性がありません。

それを解決する方法! ! ! ! ! ! ! ! ! !アップロードしています

遭遇+1

handleUploaderChange = ({file, fileList}) => {
  console.log('file vo =>', file, fileList);
  if (file.status === 'done') {
    fileList = fileList.map((item, index) => {
      // 相关文件对象数据格式化处理
      return item;
    });
  }
   // 避免原来的文件丢失,这样子写就可以了
  this.setState({ fileList: file.status ? [...fileList] : this.state.fileList });
};

// 上传进度可以通过onProgress中的percent来控制样式,而不是file.status
handleProgress = (event, file) => {
  let {fileList} = this.state;
  fileList = fileList.map(item => {
    if (item.uid === file.uid) {
      item.percent = event.percent;
    }
    return item;
  });
  this.setState({fileList});
};

ファイルのbase64が読み取られ、バックグラウンドと対話する必要がない限り、どうするか

@ pingping92

handleChange = ({ file, fileList }) => {
  const { dispatch, nickname } = this.props;
  const reader = new FileReader();
  reader.onload = e => {
    const base64 = e.target.result;
  };
  reader.readAsDataURL(file.originFileObj);
}
<Upload
  onChange={this.handleAvatarChange}
/>

@AngryPowman 、このコンポーネントに基づいて別のコンポーネントを自分でカプセル化できます。機能に関して他に満足できないものは何

ここで弱く質問しますが、新しくアップロードされたファイルがデフォルトでurlを提供しないのは意図的な設計ですか?

image

陽気な、こっけいな。これで、ファイルリストのステータスはまだアップロード中です。制御されたとしても、ステータスをアップロードに設定します。問題はまったく解決されていません

すみません、ファイルアップロード失敗フラグがバックエンドから返されます-> file.response.status。この時点では、コンポーネントはインターセプトされていません。完了すると、ファイルリストが表示されています。バックエンドから返されたフラグを使用してファイルリストをクリアしたいと思います。どうやるか?

//ピットを踏んでソースコードを調べたところ、使用した問題は次のとおりであることがわかりました。
//1.state変数の命名
//悪い

/*
这里为了方便 使用了与后端返回同样的字段 导致出了问题 这里必须用fileList,不然源码中 this.state.fileList获取是空 就会导致在onSuccess中匹配失败,从而不会在触发第二次onChange事件
*/
state = {imgList:[]} 
<Upload fileList={this.state.imgList} onChange={this.onFileChange} />

//商品

state = {fileList:[]} 
<Upload fileList={this.state.fileList} onChange={this.onFileChange} />

// 2. onFileChangeのパラメータはobj(fileとfileListの2つの属性を含む)であり、this.setState({fileList:[... fileList]});はonFileChange関数で呼び出す必要があります

state = {fileList:[]} 
onFileChange({file,fileList}) {
  if ( ... ) {
    ...
  } else {
    ...
  }
  // always setState
  this.setState({ fileList: [...fileList] });
}
<Upload fileList={this.state.fileList} onChange={this.onFileChange} />

たまたま英語はありますか? 私はこの問題を抱えています。

@developdeezあなたの問題は何ですか? どのバージョンのAntDesignを使用していますか?
以前にAntD3.0を使用し、このアップロードコンポーネントに数か月間取り組みました。 すべてがうまくいった。 問題は残っていません。 最初は問題がありましたが、最終的にはすべて修正しました。 だから私はすべての一般的な問題を解決するのに十分な自信を持っています。

@ swordguard 、Ant 3.9.3

問題は基本的にUIのファイルリストを制御できないことです。 私はアップロードして画像を作成し、ボタンを使用してクリアしようとしましたが、運がありません。

ここでもサンプルコードを使用してチケットを作成しました: https

あなたはこれをすることができましたか?

ピット+1の場合、 this.setState({ fileList: [...fileList] })を試してみ

ピット+1の場合、 this.setState({ fileList: [...fileList] })を試してみ

fileListを文字列として定義してみてください~~ == ~~
//常にsetState
this.setState({fileList:JSON.stringify([info.file])});

@ pingping92

handleChange = ({ file, fileList }) => {
  const { dispatch, nickname } = this.props;
  const reader = new FileReader();
  reader.onload = e => {
    const base64 = e.target.result;
  };
  reader.readAsDataURL(file.originFileObj);
}
<Upload
  onChange={this.handleAvatarChange}
/>

この問題は解決されていません。ファイルオブジェクトにoriginFileObj属性がありません。この属性はアップロード後にのみ表示されますか?ただし、バックグラウンドにアップロードしてbase64コンテンツを直接取得する予定はありません。

this.setState({ fileList: [...fileList] });これにより、クライアントによって表示される問題を解決できますが

ただし、必要に応じて、ファイルがアップロードされた後、バックグラウンドでファイルIDが返されます。[送信]をクリックすると、IDを返す必要がありますが、ステータスは常にアップロードされているため、バックグラウンドインターフェイスから応答を取得できません。
@ afc163

ここで同じ問題。 コンポーネントUploadでは、 actionプロパティのコールバックが呼び出されていますが、UploadFile引数には空のoriginFileObjつまりundefinedが付いています。 ファイルをバックエンドにアップロードせずにUpload antコンポーネントを使用してファイルの内容を読み取る方法の手がかりはありますか?

ここで同じ問題。 コンポーネントUploadでは、 actionプロパティのコールバックが呼び出されていますが、UploadFile引数には空のoriginFileObjつまりundefinedが付いています。 ファイルをバックエンドにアップロードせずにUpload antコンポーネントを使用してファイルの内容を読み取る方法の手がかりはありますか?

実際には、originFileObjは必要なく、ファイルオブジェクトを使用するだけです。 彼らはoriginFileObjを削除したと思います

アップロードに成功しなかったファイルをリストに追加しないようにしたかったので、ここにいます。 言い換えると、 file.status === "error"場合、そのファイルをUIに表示したくない(確かに、その障害のあるファイルをリクエストで送信したくない)。 私は自分の制御されたコンポーネントを操作し、 fileListを活用して、それを制御しようとしました。 「アップロード」から変更されないファイルステータスの問題に遭遇しました。

そのため、この問題のために、制御されたコンポーネントを使用しないことに戻りました。 normFileが「エラー」ではないファイルのみを追加するようにすることで、目的のリクエストを取得できました。

normFile = (e) => {
    if (Array.isArray(e)) {
      return e.filter(x => x.status !== "error");
    }
    return e && e.fileList.filter(x => x.status !== "error");
  };
const generationRequestDecorator = getFieldDecorator('generationRequest', {
      rules: [
        {
          required: true,
          message: 'Please upload your config'
        }
      ],
      valuePropName: 'fileList',
      getValueFromEvent: this.normFile,
    });
const props = {
      name: 'file',
      action: '/api/to/upload',
      multiple: true,
      onChange(info) {
        if (info.file.status !== 'uploading') {
          console.log(info.file, info.fileList);
        }
        if (info.file.status === 'done') {
          message.success(`${info.file.name} file uploaded successfully`);
        } else if (info.file.status === 'error') {
          message.error(`${info.file.name} file upload failed.`);
        }
      },
    };
const generationRequestArea = generationRequestDecorator(
      <Upload {...props}>
        <Button>
          <Icon type="upload"/> Click to Upload
        </Button>
      </Upload>
    );

繰り返しになりますが、antdチームが私の提案を検討してくれることを心から願っています(以前はここに書いていまし

インスタンスの状態ではなく、 Uploadインスタンスでファイルのアップロード状態を維持します。 bc状態は常に同期的に更新されるとは限りません!

私の後ろでは、バックグラウンドで返されたデータがページに個別にレンダリングされ、 Uploadは常に最新のアップロードを保存します

@yoonwaiyan
`handleChange =(情報)=> {
fileList = info.fileList;
this.setState({fileList:fileList.slice()});
if(info.file.status === '完了'){
message.success(info.file.name + "アップロード成功");
fileList = fileList.slice(-1);
fileList = fileList.map((file)=> {
if(file.response){
file.url = file.response。#応答を確認し、server#から独自のURLを選択します。
}
ファイルを返す;
});

  fileList = fileList.filter((file) => {
    if (file.response) {
      return file.response.#check your respone and choose your own respone status code back from server# === 200;
    }
    return false;
  });

  this.setState({ fileList });
} else if (info.file.status === 'error') {
  message.error(info.file.name + " upload failed");
}

} `

これを試して。

私もこの問題に遭遇しました。一連のテストの後、問題が見つかったと感じました。説明:

handleChange = info => {
    let fileList = info.fileList;
    fileList.filter(file => file.status === 'done');
    this.setState({fileList});
}

テスト状況は次のとおりです。handleChangeでthis.setState({fileList})を直接実行すると、正常に実行されます。

私の以前の記述はこれに似ています。フィルタリング後、最初の実行につながり、fileListを空の配列にフィルタリングします。したがって、アップロードの状態は常に1つだけです。
問題は、アップロード後にfileListを空の配列に手動で設定すると、onChangeイベントの継続的な実行に影響することだと思います。フィルター条件を少し変更すると、発生した問題は実際に解決されます。

公式メンテナンス中のこれら2つのプロパティ間に拘束力のある関係はありますか? @imxiongying

また、公式の場合、フィルタリング(フルコントロールアップロードリスト)のような場合がありますが、ネットワークに問題があるのではないかと思いますが、この場合も同様です。

私もこの問題に遭遇しました。一連のテストの後、問題が見つかったと感じました。説明:

handleChange = info => {
    let fileList = info.fileList;
    fileList.filter(file => file.status === 'done');
    this.setState({fileList});
}

テスト状況は次のとおりです。handleChangeでthis.setState({fileList})を直接実行すると、正常に実行されます。

私の以前の記述はこれに似ています。フィルタリング後、最初の実行につながり、fileListを空の配列にフィルタリングします。したがって、アップロードの状態は常に1つだけです。
問題は、アップロード後にfileListを空の配列に手動で設定すると、onChangeイベントの継続的な実行に影響することだと思います。フィルター条件を少し変更すると、発生した問題は実際に解決されます。

公式メンテナンス中のこれら2つのプロパティ間に拘束力のある関係はありますか?@imxiongying

また、公式の場合、フィルタリング(フルコントロールアップロードリスト)のような場合がありますが、ネットワークに問題があるのではないかと思いますが、この場合も同様です。

制御された状況下で、onChangeコールバックでfileListを空に設定すると、Uploadコンポーネント内のfileListが空の配列に更新されます。内部のonSuccess、onProgress、およびその他のロジックでは、イベントをトリガーしたファイルがfileListから検出されます。 onChangeコールバックがトリガーされます

@luruozhou Uhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh

@yidianier handleProgressこの関数はどこで呼び出されますか?

@yidianier handleProgressこの関数はどこで呼び出されますか?

onProgress = {this.handleProgress}

制御されたコンポーネントと純粋に外部に依存するコンポーネントは、それぞれのシナリオで使用されます。制御されたコンポーネントは、空白をクリックしてドロップダウンボックスをキャンセルするなど、antで論理的に制御されます。これらがすべて外部で制御されている場合、特別な気分になります。問題があるので、制御されたコンポーネントは基本ロジックの一部を担っており、コンポーネントの設計の問題ではないので、文句を言わないでください。 。 。

@すべて

@ afc163

@yidianier handleProgressこの関数はどこで呼び出されますか?

onProgress = {this.handleProgress}

ありがとう

また、この問題は3.13.1 @ afc163に発生します。

@ xiaolong1024 #14780

この問題は引き続き発生しますが、rc-formに関連していますか?

handleUploaderChange = ({file, fileList}) => {
  console.log('file vo =>', file, fileList);
  if (file.status === 'done') {
    fileList = fileList.map((item, index) => {
      // 相关文件对象数据格式化处理
      return item;
    });
  }
   // 避免原来的文件丢失,这样子写就可以了
  this.setState({ fileList: file.status ? [...fileList] : this.state.fileList });
};

// 上传进度可以通过onProgress中的percent来控制样式,而不是file.status
handleProgress = (event, file) => {
  let {fileList} = this.state;
  fileList = fileList.map(item => {
    if (item.uid === file.uid) {
      item.percent = event.percent;
    }
    return item;
  });
  this.setState({fileList});
};

この答えは私の問題を解決しました!

バージョン3.13.0では、パッケージ化後にonChangeでthis.setState({fileList})を操作すると、アップロード要求がキャンセルされます。これは開発環境では正常であり、理由を特定できません。

@ tsuijie3.13.5が修正されました。

作成者に質問したいのですが、fileOBJで応答を取得できず、アップロード後にバックエンドからfileidが返されます。私は同じ状況にあります、status ===アップロード

`import React、{Component} from'react ';
import {Upload、Icon} from'antd ';
import {urlMapToFileList、fileListTourlMap} from '@ / utils / utils';
import {upLoadFile} from '@ / services / api';

クラスUploadFormはComponent {を拡張します
static defaultProps = {
hideCheckAll:false、
};

コンストラクター(小道具){
スーパー(小道具);
console.log(urlMapToFileList(props.value));
this.state = {
filesList:urlMapToFileList(props.value)|| urlMapToFileList(props.defaultValue)|| []、
//値:urlMapToFileList(props.value)|| urlMapToFileList(props.defaultValue)|| []、
};
}

onChange = value => {
const {onChange} = this.props;
if(onChange){
const selfValue = fileListTourlMap(value);
onChange(selfValue.length?selfValue:null);
}
};
handleChange =(データ)=> {
const {file} =データ;
const {fileList} =データ;
console.log( 'handleChange'、file.status);
if(file.status === '完了'){
デバッガ
const {response} =ファイル;
if(response && response.success){
file.url = response.result.url;
fileList.pop();
fileList.push(file);
}
}
if(file.status === 'エラー'){
fileList.pop();
}

if(!file.status) {
  fileList = fileList.filter(ele => ele.url)
}
this.setState({filesList: fileList});
this.onChange(fileList);

}

render(){
const {filesList} = this.state;
戻る(

accept = "image / *"
headers = {{'x-Access-Token':localStorage.getItem( 'token')}}
action = "/ api / admin / file / upload"
listType = "picture-card"
fileList = {filesList}
onChange = {this.handleChange}
{... this.porps}
>>
{filesList.length> = 1? ヌル:

}


);
}
}

デフォルトのUploadFormをエクスポートします。
`
種は制上
@ afc163

数年前の古い問題ですが、今日はピットを踏んで遭遇したピットについても話しました。React.PureComponentを使用してコンポーネントを作成する場合、デフォルトでshouldComponentUpdateライフサイクルを通過することに注意してください。浅い比較のために、ファイルリストの状態参照アドレスは変更されていないため、アップロードコンポーネントは変更されません。

fileList = info.fileList;
/ *ここでfileList参照を変更する必要があります* /
fileList = JSON.parse(JSON.stringify(fileList));
this.setState({fileList:fileList});

3.16.1アップロードにはまだ問題があり、変更は1回だけ行われるため、更新することをお勧めします

this.setState({fileList:fileList.slice()})がこのように必要です

3.16.2 React Hookを使用する場合、fileListをonChange of Uploadにディープコピーする必要があります。lodash_.cloneDeep(fileList)を使用できます。

mobxを統合し、モーダルで2つのUploadコンポーネントを使用し、対応するストアで2つのfileListを定義します。UploadのonChangeイベントの1つは、通常のアップロードプロセスを通過します(アップロード状態と完了状態の両方が受信されます)。しかし、もう1つはがっかりしました。常にアップロードするだけで、最終的にはこの方法でしか解決できませんでした。
修改前: this.fileList[0] = file; 修改后: this.fileList = []; this.fileList.push(file);
また、this.fileListが継承されたクラスからのものである場合、変更された方法は機能しません

if (status === 'error') {
    message.success(`${file.name} upload failed.`);
    const fileList = this.state.fileList.filter(file => !file.error);
    this.setState({
        fileList
    }, () => {
        console.log(this.state.fileList)
    })
}

失敗した表示項目を削除したいのですが、どうしてこのように状態が変わらないのですか?

console.logは正しく、状態は空ですが、開発者ツールは引き続き使用可能であり、失敗したアップロード画像も表示されます

https://github.com/ant-design/ant-design/issues/2423#issuecomment -491143417

this.setState({
    fileList:[...fileList]
}

制限されたURLにIDフィールドとトークンを追加する方法は?アクションを使用してそれらを転送する方法は? アクションはアドレスを与えるだけです、あなたはデータを追加できませんか?

ヘッダーに配置できます

このトリックで私の問題を解決します
Screen Shot 1398-03-25 at 6 29 26

私は動的入力作成システムを持っていたので、新しい動的小道具を使用すると、入ってくる小道具についてantdに伝えることができます

React.Component代わりにReact.PureComponent React.Componentを使い始めたときに修正されました。

modal.infoと制御ファイルリストを使用すると、onChangeは1回だけ呼び出されます。 しかし、モーダルを削除すると、機能します

できる

1:React.Componentを使用する
2:fileListがgetDerivedStateFromPropsに設定されているかどうか、および正しく設定されているかどうかを確認するように注意してください。
3:fileList:this.state.fileList
4:onChange:({file、fileList})=> {
this.setState({fileList});
}

3.19.7にはまだこの問題があります

参考までに、成功したケースを投稿します。 しかし、私は以前にこの問題を抱えていました。 また、後で便利な検索を忘れてしまうのを容易にするために、ここで計算してメモしてください

env:

  • antd: 4.0.0-rc.1
  • プロレイアウト: 5.0.0
  • 反応: 16.9.17
import React, { useState } from 'react';
import { Modal, Upload, Button, message } from 'antd';
import { UploadOutlined } from '@ant-design/icons/lib';
import { UploadProps } from 'antd/lib/upload';
import { deleteArtifact } from '@/services/artifact';

interface UploadModalType {
  visible: boolean
  onCancel: () => void
  projectId: number
}

const UploadModal: React.FC<UploadModalType> = props => {
  const { visible, onCancel, projectId } = props;
  const [fileList, setFileList] = useState();

  const uploadProps: UploadProps = {
    name: 'file',
    fileList,
    listType: 'text',
    action: 'http://localhost:8080/v1/artifacts',
    data: { project_id: projectId, type: 'application/json' },
    onChange(info) {

      setFileList(info.fileList.slice()); // Note: A new object must be used here!!!

      if (info.file.status === 'done') {
        message.success(`${info.file.name} file uploaded successfully`);
      } else if (info.file.status === 'error') {
        message.error(`${info.file.name} file upload failed.`);
      }
    },
    onRemove(file) {
      const promise: PromiseLike<void | boolean> = deleteArtifact({ filename: file.response });
      promise.then((value: any) => {
        if (value === '' || value instanceof Response && value.status === 205) {
          const index = fileList.indexOf(file);
          const newFileList = fileList.slice();
          newFileList.splice(index, 1);
          setFileList(newFileList);
        }
      });
    },
  };

  return (
    <Modal
      destroyOnClose
      title='上传归档文件'
      visible={visible}
      onCancel={onCancel}
    >
      <Upload
        {...uploadProps}
      >
        <Button>
          <UploadOutlined/> Click to Upload
        </Button>
      </Upload>
    </Modal>
  );
};

export default UploadModal;

なんとピット、アップロード状態はfileListに設定する必要があります。そうしないと、1回だけ実行されます。

参考までに、成功したケースを投稿します。 しかし、私は以前にこの問題を抱えていました。 また、後で便利な検索を忘れてしまうのを容易にするために、ここで計算してメモしてください

env:

  • antd: 4.0.0-rc.1
  • プロレイアウト: 5.0.0
  • 反応: 16.9.17
import React, { useState } from 'react';
import { Modal, Upload, Button, message } from 'antd';
import { UploadOutlined } from '@ant-design/icons/lib';
import { UploadProps } from 'antd/lib/upload';
import { deleteArtifact } from '@/services/artifact';

interface UploadModalType {
  visible: boolean
  onCancel: () => void
  projectId: number
}

const UploadModal: React.FC<UploadModalType> = props => {
  const { visible, onCancel, projectId } = props;
  const [fileList, setFileList] = useState();

  const uploadProps: UploadProps = {
    name: 'file',
    fileList,
    listType: 'text',
    action: 'http://localhost:8080/v1/artifacts',
    data: { project_id: projectId, type: 'application/json' },
    onChange(info) {

      setFileList(info.fileList.slice()); // Note: A new object must be used here!!!

      if (info.file.status === 'done') {
        message.success(`${info.file.name} file uploaded successfully`);
      } else if (info.file.status === 'error') {
        message.error(`${info.file.name} file upload failed.`);
      }
    },
    onRemove(file) {
      const promise: PromiseLike<void | boolean> = deleteArtifact({ filename: file.response });
      promise.then((value: any) => {
        if (value === '' || value instanceof Response && value.status === 205) {
          const index = fileList.indexOf(file);
          const newFileList = fileList.slice();
          newFileList.splice(index, 1);
          setFileList(newFileList);
        }
      });
    },
  };

  return (
    <Modal
      destroyOnClose
      title='上传归档文件'
      visible={visible}
      onCancel={onCancel}
    >
      <Upload
        {...uploadProps}
      >
        <Button>
          <UploadOutlined/> Click to Upload
        </Button>
      </Upload>
    </Modal>
  );
};

export default UploadModal;

Funcコンポーネントを使用しても同じ問題が発生します。 Info.statusには常にアップロードステータスがあり、onChange呼び出しは1回だけです

@ tsuijie3.13.5が修正されました。

3.13.5私も同じ問題を抱えています。onChangeでthis.setState({fileList})を操作すると、アップロード要求がキャンセルされます。

アクションインターフェイスを使用しない場合、アップロード後、常にアップロードのステータスになります。各ファイルのステータスを手動で完了に設定する必要があります。

アクションインターフェイスを使用しない場合、アップロード後、常にアップロードのステータスになります。各ファイルのステータスを手動で完了に設定する必要があります。

fileListが状態[... fileList]を書き戻すときに、新しいオブジェクトが使用されているかどうかを確認してください。

大丈夫ありがとう

- -元の - -
差出人: "Amumu" < [email protected]>
日付:2020年7月26日日曜日17:59 PM
宛先: "ant-design / ant-design" < [email protected]>;
Cc: "コメント" < [email protected]>; "SCLGIS" < [email protected]>;
件名:Re:[ant-design / ant-design]アップロードfile.statusは常にアップロード中です(#2423)

アクションインターフェイスを使用しない場合、アップロード後、常にアップロードのステータスになります。各ファイルのステータスを手動で完了に設定する必要があります。

fileListが状態[... fileList]を書き戻すときに、新しいオブジェクトが使用されているかどうかを確認してください。


あなたがコメントしたのであなたはこれを受け取っています。
このメールに直接返信するか、GitHubで表示するか、登録を解除してください。

「複数」オプションを有効にしてフックを使用すると機能しません。
3つのファイルを選択すると、リストに2つ表示されます。 5つのファイルを選択すると、3つ、場合によっては4つしか表示されません。小道具「fileList」を削除すると、正常に機能し、リスト上のすべてのファイルを表示できますが、それらを制御できません。使用する必要があります。 「fileList」小道具。
フックuseStateの代わりにクラスコンポーネントを使用すると、動作が異なります。

4.5.1でもこの問題が発生し、常にアップロード状態でした。以前に大物が言った方法を試しましたが、うまくいきませんでした。最後にソースコードを調べたところ、レンダリングするたびにアップロードコンポーネントのキー値が異なり、再レンダリングが発生したことがわかりました。これはアップロードの状態であり、キー値は固定されており、正常にアップロードできます。

@ tsuijie3.13.5が修正されました。

3.13.5私も同じ問題を抱えています。onChangeでthis.setState({fileList})を操作すると、アップロード要求がキャンセルされます。

このページは役に立ちましたか?
0 / 5 - 0 評価