Ant-design: Upload file.status est toujours en cours de téléchargement

Créé le 18 juil. 2016  ·  90Commentaires  ·  Source: ant-design/ant-design

Environnement local

  • version antd: 1.6.5
  • Système d'exploitation et sa version: mac 10.11.5
  • Navigateur et sa version: 50.0.2661.102

Qu'avez-vous fait?

La méthode onChange du contrôle Upload de la version 1.6.5 ne sera exécutée qu'une seule fois, et info.file.status est toujours en cours de téléchargement, la requête http est normale et 200 est renvoyé.
Utilisation normale après la mise à niveau vers 1.6.4, info.file.status est effectué après le téléchargement

Le résultat que vous attendez est:

Résultat actuel:

Démo en ligne reproductible

non

Question Usage ❓FAQ

Commentaire le plus utile

Pour le mode contrôlé, vous devez toujours définirState fileList dans onChange pour vous assurer que tous les états sont synchronisés avec Upload. Semblable au libellé ici: 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} />

Il est recommandé d'étudier le concept de composants contrôlés: https://facebook.github.io/react/docs/forms.html#controlled -components


Notez que vous devez cloner fileList pour vous assurer que Upload peut détecter les changements dans le tableau.

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

Tous les 90 commentaires

Mon test actuel ne pose aucun problème, est-il pratique de donner le code complet du problème pour une reproduction facile?

Pour le mode contrôlé, vous devez toujours définirState fileList dans onChange pour vous assurer que tous les états sont synchronisés avec Upload. Semblable au libellé ici: 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} />

Il est recommandé d'étudier le concept de composants contrôlés: https://facebook.github.io/react/docs/forms.html#controlled -components


Notez que vous devez cloner fileList pour vous assurer que Upload peut détecter les changements dans le tableau.

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

e0a986ed71cd87e506fb8e4ee5e2e0130fc70ae1

Pourquoi est-ce que je ne parviens toujours pas à télécharger lorsque j'utilise le contrôle de téléchargement et que je signale toujours une erreur: POST http: // localhost : 8081 / api / nes / 2 / uploadMusic / r_ty 404 (Not Found)

Comment ajouter des champs d'identité et des jetons à des URL restreintes, comment utiliser des actions pour les transférer? L'action ne donne que des adresses, vous ne pouvez pas ajouter de données?

Il y a toujours un problème dans React.PureComponent car React.PureComponent a fait une couche de jugements d'optimisation, la liste de fichiers a des références en cache, et elle ne sera pas mise à jour s'il s'agit du même objet, et un nouvel objet doit être généré immédiatement dans React.PureComponent
handleChange = ({fileList}) => {
// bug corrigé
this.setState ({fileList: fileList.slice ()});
}

@ afc163

@yongningfu Merci pour le tuyau, il a été mis à jour.

Rappel spécial: Lors de l'utilisation de React shouldComponentUpdate pour une comparaison superficielle, en mode contrôlé, même si l'état est synchronisé avec Upload, il ne sera pas mis à jour. La raison est que la référence est congruente ===, ce qui empêche le rendu

Télécharger plusieurs images, beforeUpload définit la limite de paramètre d'image de téléchargement, onChange obtient une liste des images qui ont été téléchargées avec succès, après le téléchargement de quelques images avec succès, le téléchargement d'une image incorrecte effacera toutes les images qui ont été téléchargées avec succès auparavant, y a-t-il une solution? ?

Lorsque vous rappelez, vous devez réinitialiser l'état, tel que this.setState ({fileList});

handleChange = (info) => {
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});
}

Donc, tant que onChange change l'état, Upload sera toujours appelé en interne, non?

Ce problème existe depuis longtemps, et il s'est avéré être setState. Les composants ne doivent pas être conçus comme ça, pourquoi s'appuyer sur l'état externe paresseux?

Je veux seulement le code base64, sans interagir avec l'arrière-plan, comment résoudre le problème de l'envoi automatique des demandes en arrière-plan?

Est-ce une sculpture de sable pour maintenir cette composante?

Si le téléchargement échoue et que je souhaite afficher l'image par défaut précédente, que dois-je faire?

Le téléchargement a échoué. Dans la fonction de traitement des erreurs, appelez
this.setState ({
fileList: liste_intiale
})
Peut afficher l'image par défaut précédente

Je pense qu'il peut y avoir un problème avec la synchronisation de l'exécution du rappel lorsque le téléchargement du composant est terminé. Essayez de considérer cette situation:

Pseudo-code de relation de composant:

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

Le composant parent Controller est notifié pour mettre à jour l'état via onUpload .

Mais comme la mise à jour de l'état de React est asynchrone, si le téléchargement de l'image est suffisamment rapide, l'ordre d'exécution apparaîtra comme
constroller.onUpload(会调用 controller.setState) -> upload.onSuccess -> upload.componentWillReceiveProps
Dans le cas de l'exécution upload.onSuccess , il n'y a pas de fichier téléchargé correspondant dans l'état de téléchargement. Parce que la mise à jour de upload state.fileList dépend de componentWillReceiveProps .

Par conséquent, je pense que le mode contrôlé actuel de ce composant n'est pas fiable.

Solutions possibles:

  1. En mode contrôlé, la logique de traitement réelle onSuccess et d'autres événements placent componentDidUpdate
  2. Éviter state.fileList dépend complètement de props.fileList , maintient une relativement indépendante de la fileList (et non de l'état de l'instance de composant instance.state) sur une instance d'instance de composant, facilité de gestion du téléchargement d'événement

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

let {fichier, fileList} = info;
si (file.size / 1024/1024> 10) {
revenir
}
console.log (fichier.status)
if (file.status! = "done") {
fileList = []
}
this.setState ({
fileList,
}, console.log (
this.state.fileList,
this.props.form.getFieldValue ('upload')
))
Quand j'ajoute
if (file.status! = "done") {
fileList = []
}
Surveillez le changement une fois, supprimez-le. Pourquoi?

Ce problème n'est pas résolu, non

L'appel de setState pendant le cycle de vie du composantWillReceiveProps pour afficher l'image ne changera pas

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

Lorsque le composant de téléchargement

@PTGuan Bien sûr, ce composant est téléchargé un par un, et l'API back-end est également reçue un par un fichier. Vous devez appeler upload récursivement dans le rappel une fois le téléchargement réussi pour importer par lots. J'espère terminer votre question.

Ce problème n'est pas résolu +1

Dans antd 3.8+, il n'y a encore que status = 'loading' et aucun status done. Comment le résoudre?

Existe-t-il une solution officielle pour télécharger tout le temps, mais onSuccess peut attendre la bonne réponse http200

Le problème a été résolu, this.setState ({fileList: [... fileList]}); Cette phrase est très importante, veuillez vous concentrer dessus si vous avez des problèmes

@EnixCoda , il semble que j'ai rencontré le problème que vous avez décrit, et parfois je le télécharge et il affiche toujours "Uploading".

@withzhaoyu Eh bien, en fait, la plupart des gens ici rencontrent ce problème. Ce composant n'est pas très fiable pour stocker la progression du téléchargement via l'état React.

Comment le résoudre! ! ! ! ! ! ! ! ! ! A téléchargé

Rencontre +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});
};

Que faire tant que vous lisez la base64 du fichier sans interagir avec l'arrière-plan

@ 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 , vous pouvez encapsuler vous-même un autre composant basé sur ce composant, quoi d'autre ne peut être satisfait en termes de fonction

Demandez faiblement ici, est-ce une conception délibérée que le fichier nouvellement téléchargé ne fournit pas d'URL par défaut?

image

Hilarant. Maintenant, le statut dans la liste de fichiers est toujours en cours de téléchargement, même s'il devient contrôlé, je règle toujours le statut sur téléchargement.Le problème n'est pas du tout résolu

Excusez-moi, l'indicateur d'échec de téléchargement de fichier est renvoyé depuis le back-end -> file.response.status. Pour le moment, le composant n'est pas intercepté. Lorsque j'y vais, la liste des fichiers a été affichée. Je veux effacer la liste des fichiers via l'indicateur renvoyé par le back-end Comment faire?

// J'ai marché sur la fosse et j'ai regardé le code source et j'ai trouvé que les problèmes que j'ai utilisés sont les suivants
// 1. dénomination des variables d'état
// mal

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

// des biens

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

// 2. Le paramètre de onFileChange est un obj (comprenant deux attributs de file et fileList) et this.setState ({fileList: [... fileList]}); doit être appelé dans la fonction onFileChange

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

Un anglais par hasard? J'ai ce problème à.

@developdeez quel est votre problème? quelle version de Ant Design utilisez-vous?
J'ai utilisé AntD 3.0 auparavant et j'ai travaillé sur ce composant Upload pendant quelques mois. Tout s'est bien passé pour moi. Je n'ai eu aucun problème. J'ai eu des problèmes au début, mais je les ai finalement tous résolus. Je suis donc suffisamment confiant pour résoudre tous les problèmes courants.

@swordguard , Ant 3.9.3

Le problème est essentiellement de ne pas pouvoir contrôler la liste de fichiers de l'interface utilisateur. J'ai téléchargé et image et j'ai essayé de l'effacer en utilisant un bouton et sans chance.

J'ai également fait un ticket ici avec un exemple de code: https://github.com/ant-design/ant-design/issues/12722#event -1913716771

Avez-vous pu le faire?

En cas de pit +1, j'ai essayé this.setState({ fileList: [...fileList] }) vain, PureComponent change en Component et ce n'est pas une différence, le statut s'arrête uniquement au téléchargement à moins que fileList ne soit pas mis dans les accessoires, veuillez vous en demander beaucoup

En cas de pit +1, j'ai essayé this.setState({ fileList: [...fileList] }) vain, PureComponent change en Component et ce n'est pas une différence, le statut s'arrête uniquement au téléchargement à moins que fileList ne soit pas mis dans les accessoires, veuillez vous en demander beaucoup

Vous pouvez essayer, définir fileList comme une chaîne ~~ == ~~
// toujours 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}
/>

Ce problème n'a pas été résolu. Il n'y a pas d'attribut originFileObj dans l'objet fichier. Cet attribut n'apparaît-il qu'après le téléchargement? Mais maintenant, il n'est pas prévu de télécharger en arrière-plan et d'obtenir directement le contenu base64.

this.setState({ fileList: [...fileList] }); Bien que cela puisse résoudre le problème affiché par le client

Mais selon la demande, une fois le fichier téléversé, l'arrière-plan renvoie un identifiant de fichier. Lorsque je clique sur Soumettre, je dois renvoyer l'identifiant, mais l'état est toujours en cours de téléversement, donc je ne peux pas obtenir la réponse de l'interface d'arrière-plan.
@ afc163

Même problème ici. Dans le composant Upload le rappel action propriété originFileObj vide, c'est- undefined dire Upload ant sans télécharger le fichier sur le backend?

Même problème ici. Dans le composant Upload le rappel action propriété originFileObj vide, c'est- undefined dire Upload ant sans télécharger le fichier sur le backend?

En fait, vous n'avez pas besoin de originFileObj, utilisez simplement l'objet fichier. Je pense qu'ils ont supprimé originFileObj

Je suis ici parce que je voulais m'assurer que je n'ai pas ajouté de fichiers dans ma liste qui n'ont pas réussi le téléchargement. En d'autres termes, si mon file.status === "error" je ne veux pas afficher ce fichier dans l'interface utilisateur (certainement, je ne veux pas soumettre ce fichier défectueux dans la demande). J'ai essayé de contrôler cela en travaillant avec mon propre composant contrôlé et en exploitant fileList . Je suis tombé sur le problème dit de l'état du fichier ne changeant jamais de "téléchargement".

Je suis donc revenu à ne pas utiliser de composant contrôlé à cause de ce problème. J'ai pu obtenir la demande souhaitée en m'assurant que normFile n'ajoute que les fichiers qui ne sont pas des "erreurs".

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>
    );

Encore une fois, j'espère sincèrement que l'équipe d'antd pourra considérer ma suggestion (précédemment écrite ici ):

maintenir les états de téléchargement des fichiers sur l'instance Upload plutôt que l'état de l'instance. bc l'état n'est pas toujours mis à jour de manière synchrone!

Derrière moi, les données renvoyées par l'arrière-plan seront rendues séparément sur la page, Upload stockera toujours le dernier téléchargement

@yoonwaiyan
`handleChange = (info) => {
laissez fileList = info.fileList;
this.setState ({fileList: fileList.slice ()});
if (info.file.status === 'done') {
message.success (info.file.name + "upload success");
fileList = fileList.slice (-1);
fileList = fileList.map ((fichier) => {
if (file.response) {
file.url = file.response. # vérifiez votre réponse et choisissez votre propre URL depuis le serveur #;
}
fichier de retour;
});

  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");
}

} `

essaye ça.

J'ai également rencontré ce problème. Après une vague de tests, j'ai senti que le problème avait été détecté. Expliquez:

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

La situation de test comprend: Si vous effectuez directement this.setState({fileList}) dans handleChange, il est exécuté normalement.

Mon écriture précédente est similaire à celle-ci: après filtrage, elle mène à la première exécution, filtrant la fileList dans un tableau vide. Par conséquent, il n'y a toujours qu'un seul état de téléchargement.
Je pense que le problème est qu'après le téléchargement, si vous définissez manuellement la fileList sur un tableau vide, cela affectera l'exécution continue de l'événement onChange.Après avoir légèrement modifié les conditions de filtre, le problème rencontré est en effet résolu.

Existe-t-il une relation contraignante entre ces deux propriétés sous maintenance officielle? @Imxiongying

De plus, dans le cas officiel, il y a un tel cas avec le filtrage (liste de téléchargement de contrôle complet). Je me demande s'il y a un problème avec mon réseau. Ce cas a également cette situation.

J'ai également rencontré ce problème. Après une vague de tests, j'ai senti que le problème avait été détecté. Expliquez:

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

La situation de test comprend: Si vous effectuez directement this.setState({fileList}) dans handleChange, il est exécuté normalement.

Mon écriture précédente est similaire à celle-ci: après filtrage, elle mène à la première exécution, filtrant la fileList dans un tableau vide. Par conséquent, il n'y a toujours qu'un seul état de téléchargement.
Je pense que le problème est qu'après le téléchargement, si vous définissez manuellement la fileList sur un tableau vide, cela affectera l'exécution continue de l'événement onChange.Après avoir légèrement modifié les conditions de filtre, le problème rencontré est en effet résolu.

Existe-t-il une relation contraignante entre ces deux propriétés sous maintenance officielle? @Imxiongying

De plus, dans le cas officiel, il y a un tel cas avec le filtrage (liste de téléchargement de contrôle complet). Je me demande s'il y a un problème avec mon réseau. Ce cas a également cette situation.

Dans une situation contrôlée, définissez fileList sur empty dans le rappel onChange, et la fileList à l'intérieur du composant Upload sera mise à jour en un tableau vide. Dans sa logique interne onSuccess, onProgress et autre, le fichier qui a déclenché l'événement sera trouvé à partir de la fileList. Trigger onChange rappel

@luruozhou Uhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh , c'est comme ça

@yidianier handleProgress Où cette fonction est-elle appelée?

@yidianier handleProgress Où cette fonction est-elle appelée?

onProgress = {this.handleProgress}

Les composants contrôlés et les composants dépendants purement externes sont utilisés dans leurs scénarios respectifs. Les composants contrôlés sont contrôlés de manière logique dans ant, par exemple en cliquant sur l'espace vide pour annuler la liste déroulante, etc. Problème, donc le composant contrôlé supporte une partie de la logique de base, pas un problème avec la conception du composant, alors ne vous plaignez pas. . .

@tout

@ afc163

@yidianier handleProgress Où cette fonction est-elle appelée?

onProgress = {this.handleProgress}

Merci

Ce problème se produira également dans 3.13.1 @ afc163

@ xiaolong1024 # 14780

Ce problème persiste. Est-il lié à 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});
};

Cette réponse a résolu mon problème!

Dans la version 3.13.0, l'utilisation de this.setState ({fileList}) dans onChange après l'empaquetage entraînera l'annulation de la demande de téléchargement, ce qui est normal dans l'environnement de développement, et la raison ne peut être déterminée.

@tsuijie 3.13.5 a été corrigé.

Je voudrais demander à l'auteur, je ne peux pas obtenir la réponse sous fileOBJ et le fileid retourné par le backend après le téléchargement. J'ai la même situation, statut === téléchargement

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

La classe UploadForm étend le composant {
static defaultProps = {
hideCheckAll: faux,
};

constructeur (accessoires) {
super (accessoires);
console.log (urlMapToFileList (props.value));
this.state = {
filesList: urlMapToFileList (props.value) || urlMapToFileList (props.defaultValue) || [],
// valeur: urlMapToFileList (props.value) || urlMapToFileList (props.defaultValue) || [],
};
}

onChange = valeur => {
const {onChange} = this.props;
if (onChange) {
const selfValue = fileListTourlMap (valeur);
onChange (selfValue.length? selfValue: null);
}
};
handleChange = (données) => {
const {fichier} = données;
const {fileList} = données;
console.log ('handleChange', fichier.status);
if (file.status === 'done') {
débogueur
const {réponse} = fichier;
if (response && response.success) {
file.url = response.result.url;
fileList.pop ();
fileList.push (fichier);
}
}
if (file.status === 'erreur') {
fileList.pop ();
}

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

}

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

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

上传
}


);
}
}

Exporter UploadForm par défaut;
»
这种 控制 上传 数量 , 但 上传 状态 一直 为 téléchargement 是 啥 原因?
@ afc163

Bien que ce soit un vieux problème il y a quelques années, mais aujourd'hui, j'ai également marché sur les stands et parlé des puits que j'ai rencontrés. Si vous utilisez React.PureComponent pour créer des composants, veuillez noter qu'il passera le cycle de vie shouldComponentUpdate par défaut. Pour une comparaison superficielle, l'adresse de référence d'état de votre liste de fichiers n'a pas changé, donc le composant de téléchargement ne changera pas.

laissez fileList = info.fileList;
/ * Ici, vous devez changer la référence fileList * /
fileList = JSON.parse (JSON.stringify (fileList));
this.setState ({fileList: fileList});

3.16.1 Le téléchargement a toujours des problèmes, le changement n'est effectué qu'une seule fois, il est recommandé de mettre à jour

Besoin de this.setState ({fileList: fileList.slice ()}) de cette façon

3.16.2 Lorsque vous utilisez React Hook, fileList doit être copié en profondeur dans onChange of Upload, vous pouvez utiliser lodash _.cloneDeep (fileList)

Intégrez mobx, utilisez deux composants Upload dans un modal et définissez deux fileLists dans le magasin correspondant, l'un des événements onChange de Upload passe par le processus de téléchargement normal (les états de téléchargement et terminé sont reçus), Mais l'autre était décevant. Il n'y avait que le téléchargement tout le temps. En fin de compte, il ne pouvait être résolu que de cette manière.
修改前: this.fileList[0] = file; 修改后: this.fileList = []; this.fileList.push(file);
Et, si this.fileList provient d'une classe héritée, la méthode modifiée ne fonctionnera pas

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)
    })
}

Je souhaite supprimer l'élément d'affichage ayant échoué lorsqu'il échoue. Pourquoi l'état ne change-t-il pas de cette manière?

Le fichier console.log est correct, l'état est vide, mais les outils de développement sont toujours disponibles et les images de téléchargement ayant échoué sont également affichées

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

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

Comment ajouter des champs d'identité et des jetons à des URL restreintes, comment utiliser des actions pour les transférer? L'action ne donne que des adresses, vous ne pouvez pas ajouter de données?

Peut être placé dans l'en-tête

est résolu mon problème avec cette astuce
Screen Shot 1398-03-25 at 6 29 26

J'avais un système de création d'entrées dynamiques, donc avec les nouveaux accessoires dynamiques, vous pouvez dire à antd les accessoires à venir

Cela m'a résolu lorsque j'ai commencé à utiliser React.Component au lieu de React.PureComponent .

Lorsque j'utilise modal.info et contrôle la liste des fichiers, onChange n'est appelé qu'une seule fois. Mais quand je supprime Modal, ça marche

pouvez

1: Utilisez React.Component
2: Faites attention à vérifier si fileList est défini dans getDerivedStateFromProps et s'il est défini correctement.
3: fileList: this.state.fileList
4: onChange: ({fichier, fileList}) => {
this.setState ({fileList});
}

3.19.7 a toujours ce problème

Je poste un cas réussi pour votre référence. J'ai eu ce problème avant, cependant. Calculez également ici prendre note, afin de vous faciliter la recherche oubliée plus tard

env:

  • antd: 4.0.0-rc.1
  • mise en page pro: 5.0.0
  • réagir: 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;

Quel pit, l'état de téléchargement doit être défini sur fileList sinon, il ne sera exécuté qu'une seule fois, et après une longue période de lancer, il sera sans voix.

Je poste un cas réussi pour votre référence. J'ai eu ce problème avant, cependant. Calculez également ici prendre note, afin de vous faciliter la recherche oubliée plus tard

env:

  • antd: 4.0.0-rc.1
  • mise en page pro: 5.0.0
  • réagir: 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;

J'ai le même problème en utilisant le composant Func. Info.status a toujours le statut de téléchargement et onChange n'appelle qu'une seule fois

@tsuijie 3.13.5 a été corrigé.

3.13.5 J'ai aussi le même problème. L'opération this.setState ({fileList}) dans onChange entraînera l'annulation de la demande de téléchargement

Si vous n'utilisez pas son interface d'action, après le téléchargement, il y aura un statut de toujours téléchargement, vous devez définir manuellement le statut de chaque fichier sur terminé

Si vous n'utilisez pas son interface d'action, après le téléchargement, il y aura un statut de toujours téléchargement, vous devez définir manuellement le statut de chaque fichier sur terminé

Veuillez vérifier si le nouvel objet est utilisé lorsque la fileList réécrit l'état, [... fileList]

D'accord, merci

---Original---
De: "Amumu" < [email protected]>
Date: dim.26 juil.2020 17h59
À: "ant-design / ant-design" < [email protected]>;
Cc: "Comment" < [email protected]>; "SCLGIS" < [email protected]>;
Objet: Re: [ant-design / ant-design] Upload file.status est toujours en cours de téléchargement (# 2423)

Si vous n'utilisez pas son interface d'action, après le téléchargement, il y aura un statut de toujours téléchargement, vous devez définir manuellement le statut de chaque fichier sur terminé

Veuillez vérifier si le nouvel objet est utilisé lorsque la fileList réécrit l'état, [... fileList]

-
Vous recevez ceci parce que vous avez commenté.
Répondez directement à cet e-mail, affichez-le sur GitHub ou désabonnez-vous.

Cela ne fonctionne pas si j'utilise des crochets avec les options "multiples" activées.
Si je sélectionne 3 fichiers, j'en ai 2 sur la liste. Si je sélectionne 5 fichiers, je n'en reçois que 3, parfois 4. Si je supprime l'accessoire "fileList", cela fonctionne bien, et je peux voir tous les fichiers de la liste, mais je ne peux pas les contrôler - je dois utiliser le prop "fileList".
J'ai un comportement différent si j'utilise le composant de classe au lieu du hook useState.

J'ai également rencontré ce problème sur 4.5.1, et il était toujours à l'état de téléchargement.J'ai essayé les méthodes mentionnées par les grands joueurs auparavant, mais elles n'ont pas fonctionné. Enfin, j'ai regardé le code source et j'ai constaté que c'était parce que la valeur clé du composant d'importation était différente à chaque fois que je faisais le rendu, ce qui a conduit à un nouveau rendu. Le code source a annulé la demande d'importation précédente par défaut, ce qui a entraîné une constante C'est l'état d'uploding, la valeur de clé est fixée et ensuite elle peut être téléchargée avec succès.

@tsuijie 3.13.5 a été corrigé.

3.13.5 J'ai aussi le même problème. L'opération this.setState ({fileList}) dans onChange entraînera l'annulation de la demande de téléchargement

Cette page vous a été utile?
0 / 5 - 0 notes