web-dev-qa-db-fra.com

obtenir une valeur de promesse dans le composant de réaction

J'ai une fonction d'assistance dans mon composant. Quand je le console.log(helperFunction()), je l’obtiens dans la console.

 enter image description here

Lorsque j'essaie d'ajouter la fonction d'assistance à un champ de saisie pour obtenir sa valeur. Je reçois ceci montrant.

 enter image description here

Comment puis-je obtenir le [[PromiseValue]] dans mon entrée?

  render() {
    console.log(getProjectName());
    return (
      <form ref={(input) => this.eventForm = input} onSubmit={(e) => this.createEvent(e)} className="slds-form">
        <div className="slds-form-element">
          <label className="slds-form-element__label">Assigned To</label>
          <div className="slds-form-element__control">
            <input ref={(input) => this.assigned = input} type="text" className="slds-input"  disabled/>
          </div>
        </div>
        <div className="slds-form-element">
          <label className="slds-form-element__label">Related To</label>
          <div className="slds-form-element__control">
            <input ref={(input) => this.related = input} type="text" className="slds-input" defaultValue={getProjectName()} disabled/>
          </div>
        </div>
        <div className="slds-form-element">
          <label className="slds-form-element__label">Subject</label>
          <div className="slds-form-element__control">
            <input ref={(input) => this.subject = input} type="text" className="slds-input"/>
          </div>
        </div>
        <div className="slds-form-element">
          <label className="slds-form-element__label">Location</label>
          <div className="slds-form-element__control">
            <input ref={(input) => this.location = input} type="text" className="slds-input" />
          </div>
        </div>
        <div className="slds-form-element">
          <label className="slds-form-element__label">Event Start</label>
          <div className="slds-form-element__control">
            <input ref={(input) => this.start = input} type="text" onChange={(e) => this.onChange(e)} className="slds-input" value={ this.state.start }/>
          </div>
        </div>
        <div className="slds-form-element">
          <label className="slds-form-element__label">Event End</label>
          <div className="slds-form-element__control">
            <input ref={(input) => this.end = input} type="text" onChange={(e) => this.onChange(e)} className="slds-input" value={ this.state.end } />
          </div>
        </div>
        <div className="slds-form-element">
          <label className="slds-form-element__label">Contact</label>
          <div className="slds-form-element__control">
            <input ref={(input) => this.contact = input} type="text" className="slds-input" disabled/>
          </div>
        </div>
        <button type="button" className="slds-button slds-button--neutral">Cancel</button>
        <button type="submit" className="slds-button slds-button--brand">Create</button>
      </form>
    );
  }

Fonction d'assistance

import axios from 'axios'

export function getProjectName() {

  return new Promise(function(resolve,reject){

  // gets the record id from the current url
  function getQueryVariable(variable) {
    var query = window.location.search.substring(1);
    var vars = query.split("&");

    for (var i=0;i<vars.length;i++) {
      var pair = vars[i].split("=");
      if(pair[0] == variable){return pair[1];}
    }

    return(false);
  }

  // used to access the rest api on my system
  const REST_API_URL = restApiUrl;
  const API_TOKEN = {
    headers: { "Authorization" : "Bearer " + sessionId,
              "Content-Type" : "application/json"
             }
  }
  const OPPORTUNITY_QUERY = "SELECT+Id,Name+FROM+OPPORTUNITY+WHERE+Id="

  // get projectId
  const id = getQueryVariable('projectId');

  // make requst for record name
  var request = axios.get(`${REST_API_URL}query/?q=${OPPORTUNITY_QUERY}'${id}'`,
     API_TOKEN
   ).then(function (response){
      return resolve(response.data.records[0].Name);
   })
  })
}
6
Tyler Zika

Lorsque vous traitez avec une valeur que la méthode de rendu va utiliser et qui est également extraite de manière asynchrone, vous devriez avoir cette valeur dans l'état du composant et tirer parti de la méthode componentDidMount lifecycle pour extraire la valeur. 

class SomeComponent extends React.component {
  constructor() {
    super();

    this.state = {
      projectName: ''
    }
  }

  componentDidMount() {
    // fetch the project name, once it retrieves resolve the promsie and update the state. 
    this.getProjectName().then(result => this.setState({
      projectName: result
    }))
  }

  getProjectName() {
    // replace with whatever your api logic is.
    return api.call.something()
  }


  render() {

    return (
      <input type="text" defaultValue={projectName}>
    )
  }
 }

vous ne voulez pas appeler la fonction et résoudre la promesse dans la méthode de rendu, car la méthode de rendu doit être une fonction pure basée sur l'état et les accessoires. Ceci est un exemple de base mais devrait vous donner une idée de ce qui doit changer. Il suffit de définir projectName en tant que variable d'état et de créer et résoudre la promesse dans componentDidMount lors du premier rendu. Cette chaîne sera égale à une chaîne vide. Une fois renvoyée, elle sera mise à jour en fonction du retour de l'API.

Si vous ne souhaitez pas afficher l'entrée tant que l'appel de l'API n'est pas résolu, vous pouvez simplement ajouter des vérifications supplémentaires pour voir si this.state.projectName est égal à quelque chose et, le cas échéant, restituer l'entrée. 

7
finalfreq

Le problème avec votre code est cette partie.

<input ref={(input) => this.related = input} type="text" className="slds-input" defaultValue={getProjectName()} disabled/>.

La fonction getProjectName renvoie une promesse, pas la valeur résolue de cette promesse.

Vous devez rendre votre interface utilisateur avec render() à partir de this.state et this.props. Si vous avez des données à charger de manière asynchrone, vous pouvez les affecter à i.e. this.props.relatedTo à l'aide de la fonction componentDidMount(), quelque chose dans la ligne de

componentDidMount() {
    var self = this;

    getProjectName()
        .then(val => {
            self.setState({relatedTo: val});
        });
}

Examinez la documentation sur l'état et le cycle de vie .

1
Daniel B