web-dev-qa-db-fra.com

React - fichier de type d'entrée UI sémantique React

J'essaie d'implémenter un téléchargement de fichier, mais en utilisant SUIR <Input> , bouton, étiquette, etc.

Il s'agit strictement de l'utilisation des éléments dans le rendu.

Utilisation du html <label> et <input> éléments ce processus fonctionne comme prévu.

  <Form.Field>
    <label>File input & upload for dataschemas & datasources</label>
    <input type="file" onChange={this.fileChange} />
    <Button type="submit">Upload</Button>
  </Form.Field>

J'essaie maintenant d'utiliser SUIR <Input>, ainsi que quelques accessoires avec le <Button> élément de style.

  <Form.Field>
    <label>File input & upload </label>
    <Input type="file" onChange={this.fileChange}>
      <Button
        content="Choose File"
        labelPosition="left"
        icon="file"
      />
    </Input>
    <Button type="submit">Upload</Button>
  </Form.Field>

Vous pouvez visiter le codesandbox ici pour avoir une meilleure idée visuelle de ce dont je parle.

Lorsque je clique sur Choose File dans l'exemple d'implémentation SUIR, il n'invite pas l'utilisateur à choisir un fichier dans son système, tandis que le html <input> Est-ce que. Je ne sais pas comment obtenir <Input type="file ...> en sémantique pour se comporter de la même manière.

10
DJ2

SUIR ne fournit pas de solution de bouton FileInput prête à l'emploi. Mais vous pouvez facilement créer votre propre implémentation d'un tel bouton. Par exemple, cela se fait généralement en utilisant une entrée de fichier hidden et un bouton qui déclenche le clic d'entrée caché lorsque l'utilisateur clique dessus:

  <Button
    content="Choose File"
    labelPosition="left"
    icon="file"
    onClick={() => this.fileInputRef.current.click()}
  />
  <input
    ref={this.fileInputRef}
    type="file"
    hidden
    onChange={this.fileChange}
  />

this.fileInputRef Est un React ref créé par la méthode React.createRef(). Vous pouvez vérifier cela exemple codesandbox avec la solution ci-dessus.

17
GProst

La réponse de GProst fonctionne parfaitement bien. Dans un autre cas, vous ne souhaiterez peut-être pas créer un ref pour obtenir ce bouton d'entrée de fichier.

La solution ci-dessous utilise le prop htmlFor et transmet ce id au <input>. Ne pas utiliser ref élimine le JS supplémentaire et la communication inutile entre le bouton et l'entrée.

<Button as="label" htmlFor="file" type="button">
  Some button stuff
</Button>
<input type="file" id="file" style={{ display: "hidden" }} onChange={this.onChange} />
6
DJ2

Vous pouvez configurer le formulaire de téléchargement de fichier avec réagir comme ci-dessous.

Et vous pouvez également obtenir le nom de fichier et la référence du fichier comme démontré dans cet exemple, j'ai inclus la logique de téléchargement frontal avec axios et le code backend si vous utilisez express, node pile

class Thingy extends React.Component {
  
  uploadFile = event => {
    
    // filename
    console.log('filename ' + event.target.value);
    
    //file 
    console.log('file ' + event.target.files[0]);
    
    // if you are using axios then you can use below code
    //const formData = new FormData();
        // formData.append('file', event.target.files[0])
        // axios.put(
        //     'url',
        //     formData,
        //     { headers: { 'content-type': 'multipart/form-data' } }
        // ).then(data => {
        //     console.log('file uploaded')
        //     console.log(data)
        // }).catch(e => {
        //     console.log('error')
        //     console.log(e)
        // })
        
        // in express , node, backend code would be
        //import formidable from 'formidable'
        //(req, res) => {
        //  let form = new formidable.IncomingForm();
        //  form.parse(req, (err, fields, files) => {
            // you can get the file from files.file.path
        //  })
        // }
  }
  
  render() {
    console.log("rendered");
    return (
      <div>
        <input type="file" id="file" name="filename" onChange={this.uploadFile} />
      </div>
    );
  }
}

// Render it
ReactDOM.render(
  <Thingy/>,
  document.getElementById("react")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="react"></div>
3
NuOne