0

我知道这个错误在这里

const firstCurrency = Object.keys(data.rates)[0];

并且正因为如此,它为所有货币显示 [0]currency {toAmount} 的货币,每种货币没有不同

<table>
          {currencyOptions.map((option) => (
            <tr key={option}>
              <td>{option}</td>
              <td>{toAmount}</td>
            </tr>
          ))}
</table>

如何重写此代码以修复此应用程序页面 - 它必须显示所有当前汇率列表的更改金额

https://0b8t7.csb.app/ (codesandbox)

ExchangeRate.js

import React, { useEffect, useState } from "react";
import { Link } from "react-router-dom";
import CurrencyRow from "./CurrencyRow";

const BASE_URL = "https://api.exchangerate.host/latest";

export default function ExchangeRate() {
  const [currencyOptions, setCurrencyOptions] = useState([]);
  const [fromCurrency, setFromCurrency] = useState();
  const [toCurrency, setToCurrency] = useState();
  const [exchangeRate, setExchangeRate] = useState();
  const [amount, setAmount] = useState(1);
  const [amountInFromCurrency, setAmountInFromCurrency] = useState(true);

  let toAmount, fromAmount;
  if (amountInFromCurrency) {
    fromAmount = amount;
    toAmount = amount * exchangeRate;
  } else {
    toAmount = amount;
    fromAmount = amount / exchangeRate;
  }
  useEffect(() => {
    fetch(BASE_URL)
      .then((res) => res.json())
      .then((data) => {
        if (!data || !data.rates) return;
        const firstCurrency = Object.keys(data.rates)[0];
        setCurrencyOptions([data.base, ...Object.keys(data.rates)]);
        setFromCurrency(data.base);
        setToCurrency(firstCurrency);
        setExchangeRate(data.rates[firstCurrency]);
      });
  }, []);

  useEffect(() => {
    if (fromCurrency != null && toCurrency != null) {
      fetch(`${BASE_URL}?base=${fromCurrency}&symbols=${toCurrency}`)
        .then((res) => res.json())
        .then((data) => setExchangeRate(data.rates[toCurrency]));
    }
  }, [fromCurrency, toCurrency]);

  function handleFromAmountChange(e) {
    setAmount(e.target.value);
    setAmountInFromCurrency(true);
  }

  function handleToAmountChange(e) {
    setAmount(e.target.value);
    setAmountInFromCurrency(false);
  }

  return (
    <>
      <CurrencyRow
        currencyOptions={currencyOptions}
        selectedCurrency={fromCurrency}
        onChangeCurrency={(e) => setFromCurrency(e.target.value)}
        onChangeAmount={handleFromAmountChange}
        amount={fromAmount}
      />
      <div>
        <table>
          {currencyOptions.map((option) => (
            <tr key={option}>
              <td>{option}</td>
              <td>{toAmount}</td>
            </tr>
          ))}
        </table>
      </div>
      <Link to="/">
        <div id="wrapper">
          <div id="wrapper-inner">
            <div id="scroll-up">
              <span class="arrow-up"></span>
            </div>
          </div>
        </div>
      </Link>
    </>
  );
}

CurrencyRow.js

import React from "react";

export default function CurrencyRow(props) {
  const {
    currencyOptions,
    selectedCurrency,
    onChangeCurrency,
    onChangeAmount,
    amount
  } = props;

  return (
    <div className="CurrencyRow">
      <select
        className="select"
        value={selectedCurrency}
        onChange={onChangeCurrency}
      >
        {currencyOptions.map((option) => (
          <option key={option} value={option}>
            {option}
          </option>
        ))}
      </select>
      <input
        type="number"
        className="input"
        value={amount}
        onChange={onChangeAmount}
      />
    </div>
  );
}

主页.js

import React from "react";
import { Link } from "react-router-dom";
import CurrencyConverter from "./CurrencyConverter";

export default function Home() {
  return (
    <>
      <h1>
        <span className="text1">DYNAMIC</span>
        <br />
        <span className="text2">&&FREE</span>
        <br />
        <span className="text3">&&EASY</span>
        <br />
        <span className="text4">&&FAST</span>
        <br />
        <span className="text5">CURRENCY</span>
        <br />
        <span className="text6">CONVERSION</span>
        <br />
      </h1>
      <CurrencyConverter />
      <Link to="/exchange">
        <div id="wrapper">
          <div id="wrapper-inner">
            <div id="scroll-down">
              <span class="arrow-down"></span>
            </div>
          </div>
        </div>
      </Link>
    </>
  );
}

CurrencyConverter.js

import React, { useEffect, useState } from "react";
import CurrencyRow from "./CurrencyRow";

const BASE_URL = "https://api.exchangerate.host/latest";

export default function CurrencyConverter() {
  const [currencyOptions, setCurrencyOptions] = useState([]);
  const [fromCurrency, setFromCurrency] = useState();
  const [toCurrency, setToCurrency] = useState();
  const [exchangeRate, setExchangeRate] = useState();
  const [amount, setAmount] = useState(1);
  const [amountInFromCurrency, setAmountInFromCurrency] = useState(true);

  let toAmount, fromAmount;
  if (amountInFromCurrency) {
    fromAmount = amount;
    toAmount = amount * exchangeRate;
  } else {
    toAmount = amount;
    fromAmount = amount / exchangeRate;
  }

  useEffect(() => {
    fetch(BASE_URL)
      .then((res) => res.json())
      .then((data) => {
        if (!data || !data.rates) return;
        const firstCurrency = Object.keys(data.rates)[0];
        setCurrencyOptions([data.base, ...Object.keys(data.rates)]);
        setFromCurrency(data.base);
        setToCurrency(firstCurrency);
        setExchangeRate(data.rates[firstCurrency]);
      });
  }, []);

  useEffect(() => {
    if (fromCurrency != null && toCurrency != null) {
      fetch(`${BASE_URL}?base=${fromCurrency}&symbols=${toCurrency}`)
        .then((res) => res.json())
        .then((data) => setExchangeRate(data.rates[toCurrency]));
    }
  }, [fromCurrency, toCurrency]);

  function handleFromAmountChange(e) {
    setAmount(e.target.value);
    setAmountInFromCurrency(true);
  }
  function handleToAmountChange(e) {
    setAmount(e.target.value);
    setAmountInFromCurrency(false);
  }

  return (
    <>
      <CurrencyRow
        currencyOptions={currencyOptions}
        selectedCurrency={fromCurrency}
        onChangeCurrency={(e) => setFromCurrency(e.target.value)}
        onChangeAmount={handleFromAmountChange}
        amount={fromAmount}
      />
      <CurrencyRow
        currencyOptions={currencyOptions}
        selectedCurrency={toCurrency}
        onChangeCurrency={(e) => setToCurrency(e.target.value)}
        onChangeAmount={handleToAmountChange}
        amount={toAmount}
      />
    </>
  );
}

应用程序.js

import React from "react";
import Home from "./components/Home";
import ExchangeRate from "./components/ExchangeRate";
import "./styles.css";
import {
  BrowserRouter as Router,
  Switch,
  Route,
  Redirect
} from "react-router-dom";

export default function App() {
  return (
    <>
      <Router>
        <Switch>
          <Route exact path="/" component={Home} />
          <Route path="/exchange" component={ExchangeRate} />
          <Redirect to="/" />
        </Switch>
      </Router>
    </>
  );
}
4

1 回答 1

0

在 ExchangeRate.js 中添加(更改一个 useEffect()):

const [newEx, setNewEx] = useState();

useEffect(() => {
    const requares = currencyOptions.map((i) =>
      fetch(`${BASE_URL}?base=${fromCurrency}&symbols=${i}`)
    );
    Promise.all(requares)
      .then((res) => Promise.all(res.map((i) => i.json())))
      .then((res) => res.reduce((acc, obj) => ({ ...acc, ...obj.rates }), {}))
      .then((res) => setNewEx(res));
  }, [fromCurrency, toCurrency, currencyOptions]);

作为回报:

<table>
          {newEx &&
            currencyOptions.map((option) => (
              <tr key={option}>
                <td>{option}</td>
                <td>{amount * newEx[option]}</td>
              </tr>
            ))}
</table>
于 2022-02-16T21:25:58.523 回答