I added a TextField
from the MUI library, and used a useRef
hook to capture the value "live" as the user types something. The intention is to filter only the rates which include the characters he types. As of right now:
Object.keys(rates["rates"]) // ["EUR", "RON", "CZK", ...]
I added a form, and I want it to stay persistent, but the buttons should change dynamically. If the user has not typed anything I want to return everything (like nothing is filtered)
My try:
import React, {useEffect, useRef, useState} from 'react'
import Button from '@mui/material/Button';
import CircularProgress from '@mui/material/CircularProgress';
import Box from '@mui/material/Box';
import TextField from '@mui/material/TextField';
const RatesButton = () => {
const rateRef = useRef('')
const [rates, setRates] = useState([]);
useEffect(
() => {
fetch("https://api.vatcomply.com/rates")
.then(ratesResponse => ratesResponse.json())
.then(rates => setRates(rates));
}
, [])
if (rates.length === 0) {
return (
<Box sx={{display: 'flex', justifyContent: 'center'}}>
<CircularProgress/>
</Box>
)
}
const rateSearch = () => {
Object.keys(rates["rates"]).filter(
rate => rate.includes(rateRef.current.value)
).map(rate => {
return (
<Button>
{rate}
</Button>
)
}
)
}
return (
<>
<br/>
<TextField id="rate-search" onChange={rateSearch} inputRef={rateRef} label="Rate" variant="outlined"/>
</>
)
}
export default RatesButton
It works nicely I think, I can access the reference of the input of the user, filter all the rates that contain the letters, and map each one to a MUI Button
. The problem is that they don't show somehow, and I am pretty lost, it is pretty confusing how I can return from two different functions at the same time, while keeping one persistent (the input field)
The buttons do not show unfortunately...
CodePudding user response:
CodePudding user response:
import React, {useState} from 'react';
import { throttle } from 'lodash';
const RatesButton = () => {
const [value, setValue] = useState("");
const [rates, setRates] = useState({});
useEffect(() => {
fetch("https://api.vatcomply.com/rates")
.then((ratesResponse) => ratesResponse.json())
.then((rates) => setRates(rates.rates ?? {}));
}, []);
const handleChange = (e) => setValue(e.target.value);
// it will prevent multiple render during fast typing
const throttledChange = throttle(handleChange, 400);
return (
<>
{Object.keys(rates).length === 0 && (
<Box sx={{ display: "flex", justifyContent: "center" }}>
<CircularProgress />
</Box>
)}
{Object.keys(rates)
.filter((rate) => rate.toLowerCase().includes(value.toLowerCase()))
.map((rate) => {
return <Button>{rate}</Button>;
})}
<br />
<TextField
id="rate-search"
onChange={throttledChange} // don't use arrow function
label="Rate"
variant="outlined"
/>
</>
);
};