在反应组件中获得承诺值

Posted

技术标签:

【中文标题】在反应组件中获得承诺值【英文标题】:get promise value in react component 【发布时间】:2017-07-07 14:07:32 【问题描述】:

我的组件中有一个辅助函数。当我console.log(helperFunction()) 它时,我会在控制台中得到它。

当我尝试将辅助函数添加到其值的输入字段时。我得到了这个显示。

如何在我的输入中获得[[PromiseValue]]

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

辅助函数

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_URLquery/?q=$OPPORTUNITY_QUERY'$id'`,
     API_TOKEN
   ).then(function (response)
      return resolve(response.data.records[0].Name);
   )
  )

【问题讨论】:

您打印出的是 promise 对象而不是已解析的值,但除非您跳过图像并发布一些代码,否则很难说您做错了什么。 @DanielB 完成,对不起 @DanielB 如何打印解析的值? getProjectName() 返回一个承诺。如果该承诺解析了一个值,则应该可以只运行getProjectName().then((value) =&gt; console.log(value); );,但如果包含getProjectName 函数的代码会更好。 但是如何将解析后的值放入我的 jsx 中的 input 中? 【参考方案1】:

在处理渲染方法将使用并且异步检索的值时,您应该让该值存在于组件的状态中,并利用componentDidMount 生命周期方法来检索该值。

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

你不想在 render 方法中调用函数并解析 promise,因为 render 方法应该是一个基于 state 和 props 的纯函数。这是一个基本示例,但应该让您了解需要更改的内容。只需将projectName 设置为状态变量,并在第一次渲染时生成并解析componentDidMount 中的promise,它将等于一个空字符串,一旦返回,它将更新为api 返回的任何内容。

如果您不想在 api 调用解决之前显示输入,那么您可以添加额外的检查以查看 this.state.projectName 是否等于任何内容,如果是则呈现输入。

【讨论】:

【参考方案2】:

你的代码的问题是这部分。

&lt;input ref=(input) =&gt; this.related = input type="text" className="slds-input" defaultValue=getProjectName() disabled/&gt;.

函数getProjectName 返回一个promise,而不是该promise 的解析值。

您应该使用this.statethis.props 中的render() 呈现您的UI,如果您有必须异步加载的数据,您可以使用componentDidMount() 函数将数据分配给即this.props.relatedTo

componentDidMount() 
    var self = this;

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

看看the state and lifecycle documentation。

【讨论】:

你太棒了!谢谢!

以上是关于在反应组件中获得承诺值的主要内容,如果未能解决你的问题,请参考以下文章

如何获得有关反应中下拉值变化的数据?

直接从 vue 3 设置中获得的道具不是反应式的

如何获得一个反应组件树,就像它在反应开发工具中显示的那样?

尝试在反应组件的返回中使用 setstate 更新状态并获得“最大更新深度超出错误”?

JavaScript 中的 Promise.all:如何获得所有承诺的解析值?

获取反应组件的未定义值 |节点js |反应