#javascript #reactjs
#javascript #reactjs
Вопрос:
У меня есть скрипт, который вызывает API из React.
У меня есть массив символов const assets = ['ADA','KAVA','DOGE'];
Моя строка API выглядит следующим образом
https://min-api.cryptocompare.com/data/pricemulti?fsyms=${symbol}amp;tsyms=USDamp;api_key=API-KEY-HERE
Как вы можете видеть, я вызываю API 3 раза для каждого символа, например, если я запущу этот код, он будет выполняться 3 раза
https://min-api.cryptocompare.com/data/pricemulti?fsyms=ADAamp;tsyms=USDamp;api_key=API-KEY-HERE
https://min-api.cryptocompare.com/data/pricemulti?fsyms=KAVAamp;tsyms=USDamp;api_key=API-KEY-HERE
https://min-api.cryptocompare.com/data/pricemulti?fsyms=DOGEamp;tsyms=USDamp;api_key=API-KEY-HERE
Как я могу вызвать API, чтобы использовать весь массив при вызове API. Предполагается, что в конце строки это будет так
https://min-api.cryptocompare.com/data/pricemulti?fsyms=ADA,KAVA,DOGEamp;tsyms=USDamp;api_key=API-KEY-HERE
;
Я также знаю, что могу написать это как этот «жесткий сценарий», но мне нужно использовать параметры в массиве для будущих функций, таких как сценарий уведомления по электронной почте.
Вот мой полный код:
import React, { useState, useEffect} from "react";
import axios from "axios";
require('dotenv').config()
const assets = ['ADA','KAVA','DOGE'];
export default function App() {
const [queries, setQueries] = useState(
JSON.parse(localStorage.getItem("queries")) || []
);
const [symbol, setSymbol] = useState("");
const [price, setPrice] = useState("");
const [dropdown, setDropdown] = useState([]);
const [dataApi, setDataApi] = useState([]);
const [filtered, setFiltered] = useState([]);
useEffect(() => {
setTimeout(() => {
getApiData();
}, 1000 * 60);
if (dataApi.length > 0) {
const clientQueriesNames = queries.map(rec => rec.symbol);
const newFilteredArray = dataApi.filter(apiQuery => {
if (clientQueriesNames.includes(apiQuery.Symbol)) {
return apiQuery.Open >
queries.find(rec => rec.symbol === apiQuery.Symbol).price
? apiQuery
: false;
}
});
const newQueries = queries.filter(rec => {
return typeof newFilteredArray.find(
query => query.Symbol === rec.symbol
) === "undefined"
? rec
: false;
});
setFiltered(newFilteredArray);
setQueries(newQueries);
localStorage.setItem("queries", JSON.stringify(newQueries));
newFilteredArray.forEach(query => {
window.Email.send({
Host: "smtp.gmail.com",
Username: process.env.REACT_APP_DB_USER,
Password: process.env.REACT_APP_DB_PASS,
To: process.env.REACT_APP_DB_RECEIVER,
From: process.env.REACT_APP_DB_USER,
Subject: `${query.Symbol} is up`,
Body: `${query.Symbol} is UP`
});
console.log(newFilteredArray);
}
}, [dataApi]);
const getApiData = () => {
const getString = symbol =>
`https://min-api.cryptocompare.com/data/pricemulti?fsyms=${symbol}amp;tsyms=USDamp;api_key=API-KEY-HERE`;
function getAxious(id) {
const url = getString(id);
return axios.get(url);
}
const BUCKET_SIZE = 150;
const bucketArray = assets.reduce(
(arr, rec) => {
if (arr[arr.length - 1].length < BUCKET_SIZE) {
arr[arr.length - 1] = [...arr[arr.length - 1], rec];
return arr;
}
return [...arr, [rec]];
},
[[]]
);
bucketArray
.reduce((acc, rec) => {
return acc.then(results => {
return Promise.all(
rec.map(item =>
getAxious(item).then(({ data }) => {
return {
Symbol: item,
Open: data
};
})
)
).then(x => {
return [...x, ...results];
});
});
},
Promise.resolve([]))
.then(res => {
setDataApi(res);
});
};
const onChangeSymbol = e => {
setSymbol(e.target.value);
};
const onChangePrice = e => {
setPrice(e.target.value);
};
var today = new Date();
var date =
today.getFullYear() "-" (today.getMonth() 1) "-" today.getDate();
var time =
today.getHours() ":" today.getMinutes() ":" today.getSeconds();
var dateTime = date " " time;
const onClick = () => {
if (symbol !== "" amp;amp; price !== "") {
setQueries(queries => {
const query = {
symbol,
price,
dateTime
};
localStorage.setItem("queries", JSON.stringify([...queries, query]));
return [...queries, query];
});
setSymbol("");
setPrice("");
}
};
useEffect(() => {
if (symbol !== "" amp;amp; symbol !== assets.find(rec => rec === symbol)) {
setDropdown(assets.filter(rec => rec.indexOf(symbol) > -1));
} else {
setDropdown([]);
}
}, [symbol]);
return (
<div id="DropDownArea" className="DropDownField">
<div id="PriceAlertHistory">
<h6>Price Alert History</h6>
</div>
<ul>
{queries.map(query => (
<li key={query.symbol}>
{`${query.symbol}`
" "
`${query.price}`
" "
"("
query.dateTime
")"}
<button
onClick={() => {
const newQueries = queries.filter(
rec => rec.symbol !== query.symbol
);
setQueries(newQueries);
localStorage.setItem("queries", JSON.stringify(newQueries));
}}
>
X
</button>
</li>
))}
</ul>
<input
type="text"
placeholder="Symbol"
value={symbol}
onChange={onChangeSymbol}
/>
<input
type="number"
placeholder="Price"
value={price}
onChange={onChangePrice}
/>
<button type="submit" onClick={onClick}>
Set
</button>
<ul>
{dropdown.length !== 0
? dropdown.map(asset => {
return (
<li
onClick={() => {
setSymbol(asset);
setDropdown([]);
}}
>
{asset}
</li>
);
})
: false}
</ul>
</div>
);
}
Комментарии:
1.
process.env.REACT_APP_DB_PASS
на стороне клиента? eek
Ответ №1:
Вы можете использовать функцию объединения массива следующим образом
const assets = ['ADA','KAVA','DOGE'];
assets.join(",");
Результат будет
ADA,KAVA,DOGE
Если ваш API не позволяет этого, попробуйте использовать подобные обещания.
let promises = [];
array.map(item => promises.push(<YOUR URL>));
Promise.All(promises).then(responses => {
//YOUR RESPONSES OF APIS IN THE EXACT SEQUENCE AS THEY ARE PUSHED
}).catch(error => {
//YOUR ERROR HANDLING
});
Комментарии:
1. Привет! Спасибо за ответ, к сожалению, он по-прежнему вызывает 3 вызова API вместо одного.