Javascript 在反应组件中获取承诺值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/42308244/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
get promise value in react component
提问by Tyler Zika
I have a helper function in my component. When I console.log(helperFunction())it, I get this in the console.
我的组件中有一个辅助函数。当我console.log(helperFunction())它时,我在控制台中得到了这个。
When I try to add the helper function to an input field for its value. I get this showing up.
当我尝试将辅助函数添加到输入字段以获取其值时。我得到这个出现。
How do I get the [[PromiseValue]]in my input?
我如何[[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>
);
}
Helper Function
辅助功能
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);
})
})
}
回答by finalfreq
When dealing with a value that the render method will be using and is also retrieved asynchronously you should be having that value exist in the state of the component and take advantage of the componentDidMountlifecycle method to retrieve the value.
当处理渲染方法将使用的值并且也被异步检索时,您应该让该值存在于组件的状态中,并利用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}>
)
}
}
you don't want to call the function and resolve the promise in the render method because render method should be a pure function based on state and props. This is a base example but should give you an idea of what needs to change. Just need to set projectNameas a state variable and make and resolve the promise in the componentDidMounton the first render it will equal an empty string, once it comes back it will update to whatever the api returns.
您不想调用该函数并在 render 方法中解析 promise,因为 render 方法应该是基于 state 和 props 的纯函数。这是一个基本示例,但应该可以让您了解需要更改的内容。只需要设置projectName为状态变量,并componentDidMount在第一次渲染时制作并解析承诺,它将等于一个空字符串,一旦返回,它将更新为 api 返回的任何内容。
If you don't want to show the input until the api call resolves then you can just add additional checks to see if this.state.projectNameequals anything and if so render the input.
如果您不想在 api 调用解析之前显示输入,那么您可以添加额外的检查以查看是否this.state.projectName等于任何内容,如果是,则呈现输入。
回答by Daniel B
The problem with your code is this part.
您的代码的问题是这一部分。
<input ref={(input) => this.related = input} type="text" className="slds-input" defaultValue={getProjectName()} disabled/>.
<input ref={(input) => this.related = input} type="text" className="slds-input" defaultValue={getProjectName()} disabled/>.
The function getProjectNamereturns a promise, not the resolved value of that promise.
该函数getProjectName返回一个承诺,而不是该承诺的解析值。
You should render your UI with render()from this.stateand this.props, and if you have data that has to be loaded asynchronously, you can assign the data to i.e. this.props.relatedTousing the componentDidMount()function, something in the line of
您应该使用render()fromthis.state和来呈现您的 UI this.props,并且如果您有必须异步加载的数据,您可以this.props.relatedTo使用该componentDidMount()函数将数据分配给 ie ,例如
componentDidMount() {
var self = this;
getProjectName()
.then(val => {
self.setState({relatedTo: val});
});
}
Take a look at the state and lifecycle documentation.
查看状态和生命周期文档。


