reactjs - 从返回链接的承诺中获取价值
问题描述
我正在建立一个 ReactJS 网站。
我想通过调用异步函数来访问我的 render() 方法中的链接。我的代码实际上如下:
<a href={this.getDownloadURL(note.noteId)}>
<span className="downloadAction">
DOWNLOAD
<img className="logoImageRight" src={require("../imgs/download.png")} alt="NotFound"/>
</span>
</a>
我的函数 getDownloadURL() :
async getDownloadURL(noteId){
var attachmentURL;
const note = await this.getNote(noteId);
const {attachment} = note;
if(attachment){
attachmentURL = await Storage.vault.get(attachment);
}
return(attachmentURL);
}
目前我的链接类似于http://localhost:3000/[object Promise],这意味着(我认为)我的承诺在我创建链接时还没有完成。有没有人有解决方案如何使我的应答器中的链接正确?
编辑 :
import React, { Component } from "react";
import { ListGroupItem } from "react-bootstrap";
import { FormGroup, FormControl, ControlLabel, Label } from "react-bootstrap";
import { LinkContainer } from "react-router-bootstrap";
import { API, Storage } from "aws-amplify";
import "./RawList.css";
import { MdMessage } from 'react-icons/md';
export default class RawList extends Component {
constructor(props) {
super(props);
this.state = {
isLoading: true,
notes: [],
inputValue: 0,
reducedView: true
};
}
async componentDidMount() {
try {
const notes = await this.notes();
this.setState({ notes });
} catch (e) {
alert(e);
}
this.setState({ isLoading: false });
}
notes() {
return API.get("notes", "/notes");
}
getType(attachment){
if(attachment === undefined){
return("");
}
var tmpString = attachment.split('/')[0];
if(tmpString === "Oil&GasLease"){
return("Oil & Gas Lease");
}
else if(tmpString === "Oil&GasWell"){
return("Oil & Gas Well");
}
else if(tmpString === "OilMaster"){
return("Oil Master");
}
else if(tmpString === "GasMaster"){
return("Gas Master");
}
else if(tmpString === "OilWellW10"){
return("Oil Well W10");
}
else{
return("Unknown Type");
}
}
formatFilename(value){
return(value);
}
displayNew(date){
if(parseInt((Date.now() - date) / 3600000) < 1){
return(
<img className="LogoNew" src={require("../imgs/new.png")} alt="NotFound"/>
);
}
}
getFilename(str){
return(str.split('\\').pop().split('/').pop().split('-')[1]);
}
handleClick(e) {
this.setState({ reducedView: false });
e.preventDefault();
}
getNote(noteID) {
return API.get("notes", `/notes/`+noteID);
}
async getDownloadURL(noteId){
var attachmentURL;
const note = await this.getNote(noteId);
const {attachment} = note;
if(attachment){
attachmentURL = await Storage.vault.get(attachment);
}
return(attachmentURL);
}
renderNotesList(notes) {
return [{}].concat(notes).map(
(note, i) => {
if(i !== 0){
if(i >= 6 && notes.length >= 6 && this.state.reducedView){
if(i === 6){
return(
<ListGroupItem>
<img onClick={this.handleClick.bind(this)} src={require("../imgs/3dots.png")} alt="NotFound"/>
</ListGroupItem>
);
}
}
else{
return(
<ListGroupItem className="mainContainer">
<div className="column1">
<img className="Logo" src={require("../imgs/ebc.png")} alt="NotFound"/>
</div>
<div className="column2">
<b>{this.getFilename(note.attachment)}</b>
{this.displayNew(note.createdAt)}
</div>
<div className="column3">
{this.humanFileSize(note.input_fileSize)}
</div>
<div className="column4">
{this.getType(note.attachment)}
</div>
<div className="column5">
{new Date(note.createdAt).toLocaleString()}
</div>
<div className="column6">
<a href={'/notes/'+note.noteId}><MdMessage className="commentLogo" size={20}></MdMessage></a>
</div>
<div className="column7">
<span className="convertionAction">
CONVERT
<img className="logoImageLeft" src={require("../imgs/convertion.png")} alt="NotFound"/>
</span>
</div>
<div className="column8">
<a href={this.getDownloadURL(note.noteId)}>
<span className="downloadAction">
DOWNLOAD
<img className="logoImageRight" src={require("../imgs/download.png")} alt="NotFound"/>
</span>
</a>
</div>
<div className="column9">
<div className="tripleDot"></div>
</div>
</ListGroupItem>
);
}
}
else{
if(notes.length === 0){
return(
<div>
<ListGroupItem>
<div className="column2Header">
File
</div>
<div className="column3Header">
Size
</div>
<div className="column4Header">
Type
</div>
<div className="column5Header">
Date
</div>
<div className="column6Header">
Comment
</div>
</ListGroupItem>
<LinkContainer key={note.noteId} to={`/upload`}>
<ListGroupItem className="upload">
<div className="noUpload">
+ Create new upload
</div>
</ListGroupItem>
</LinkContainer>
<div className="errorMessage">
You don't have any existing upload yet.
</div>
</div>
);
}
else{
return(
<div>
<ListGroupItem>
<div className="column2Header">
File
</div>
<div className="column3Header">
Size
</div>
<div className="column4Header">
Type
</div>
<div className="column5Header">
Date
</div>
<div className="column6Header">
Comment
</div>
</ListGroupItem>
<LinkContainer key={note.noteId} to={`/upload`}>
<ListGroupItem className="upload">
<div className="noUpload">
+ Create new upload
</div>
</ListGroupItem>
</LinkContainer>
</div>
);
}
}
}
);
}
humanFileSize(bytes) {
var thresh = 1024;
if(Math.abs(bytes) < thresh) {
return bytes + ' B';
}
var units = ['KiB','MiB','GiB','TiB','PiB','EiB','ZiB','YiB'];
var u = -1;
do {
bytes /= thresh;
++u;
} while(Math.abs(bytes) >= thresh && u < units.length - 1);
return bytes.toFixed(1)+''+units[u];
}
handleInputChange = event => {
var e = document.getElementById("DropdownList");
var tmp = parseInt(e.options[e.selectedIndex].value);
if(tmp === 1){
this.state.notes.sort(function(a,b){
return this.getType(a.attachment) > this.getType(b.attachment);
}.bind(this))
}
else if(tmp === 2){
this.state.notes.sort(function(a,b){
return this.getType(a.attachment) < this.getType(b.attachment);
}.bind(this))
}
else if(tmp === 3){
this.state.notes.sort(function(a,b){
return a.attachment < b.attachment;
})
}
else if(tmp === 4){
this.state.notes.sort(function(a,b){
return a.attachment > b.attachment;
})
}
else if(tmp === 5){
this.state.notes.sort(function(a,b){
return a.fileSize < b.fileSize;
})
}
else if(tmp === 6){
this.state.notes.sort(function(a,b){
return a.fileSize > b.fileSize;
})
}
else if(tmp === 7){
this.state.notes.sort(function(a,b){
return a.createdAt > b.createdAt;
})
}
else if(tmp === 8){
this.state.notes.sort(function(a,b){
return a.createdAt < b.createdAt;
})
}
this.setState({ inputValue: tmp });
}
render() {
return (
<div className="Supervision">
<div className="notes">
<FormGroup onChange={this.handleInputChange}>
<ControlLabel>Order By :</ControlLabel><br/>
<select id="DropdownList">
<option value="0">...</option>
<option value="1">Type ascending</option>
<option value="2">Type descending</option>
<option value="3">Filename ascending</option>
<option value="4" >Filename descending</option>
<option value="5">Size ascending</option>
<option value="6" >Size descending</option>
<option value="7">Date ascending</option>
<option value="8">Date descending</option>
</select>
</FormGroup>
{!this.state.isLoading && this.renderNotesList(this.state.notes)}
</div>
</div>
);
}
}
解决方案
您可以加载下载 URL 并将其置于状态,例如:
function App() {
const [url, setUrl] = React.useState('')
React.useEffect(() => {
getDownloadURL().then(setUrl)
}, [])
async function getDownloadURL(){
return await Promise.resolve('foo')
}
return (
<a href={url}>
<span className="downloadAction">
DOWNLOAD
</span>
</a>
);
}
要点是将下载 URL 置入状态,以便您渲染任何处于状态的内容,就像您对 in 所做的notes
那样componentDidMount
。您可以创建一个DownloadLink
组件,如:
class DownloadLink extends React.Component {
state = { url: "" };
componentDidMount() {
const { noteId } = this.props;
this.getDownloadURL(noteId).then(url => this.setState({ url }));
}
getDownloadURL = async function(noteId) {
// for example
return await Promise.resolve(`foo/${noteId}`);
};
render() {
return (
<a href={this.state.url}>
<span className="downloadAction">DOWNLOAD</span>
</a>
);
}
}
在您的RawList
组件中,您可以使用它,而不是:
<div className="column8">
<a href={this.getDownloadURL(note.noteId)}>
<span className="downloadAction">
DOWNLOAD
<img className="logoImageRight" src={require("../imgs/download.png")} alt="NotFound"/>
</span>
</a>
</div>
使用DownloadLink
类似:
<div className="column8">
<DownloadLink noteId={note.noteId} />
</div>
(如果getDownloadURL
在 DownloadLink 中需要更多数据,RawList
您可以将其作为道具传递)
推荐阅读
- python - 用 cesar 密码加密文本,str.replace 给出 TypeError: Can't convert 'NoneType' object to str 隐式
- c - Can I use SIMD to bucket sort / categorize?
- python - Scipy curve_fit silently fails only for very specific x-values
- android - How to launch app by scanning NDEF NFC tag?
- r - R如何在给定的符号处切割列表并输出数据框?
- angular - Angular http post adds multiple empty objects after adding user data to json
- regex - Regex to allow only lowercase characters and numbers
- java - Powermock - 试图模拟方法实际上调用方法
- javascript - Responsive D3 Donut Chart
- java - 如何在 jfxtableview 中移动行