I'm trying to create a basic list when I send a request every time with useLazyQuery.
This is my App component. As you can see, I use network-only fetchPolicy but I still get some problems. Firstly, I delete an item from the list. After I delete an item, I want to add the same value to the list. However, onCompleted has not been called.
Also, onCompleted has not been called again when I try to send the last request. I tried no-cache fetchPolicy but I still get some problems. It's not working properly. What am I doing wrong?
const App = () => {
const [code, setCode] = useState('');
const [coins, setCoins] = useState([]);
const [getData, { loading, data, error }] = useLazyQuery(GET_COIN_PRICE_QUERY, {
variables: { code },
fetchPolicy: 'network-only',
onCompleted: (data) => {
const hasSameCoin = coins.some((f) => f.id === data.markets[0]?.id);
if (data.markets.length && !hasSameCoin) {
setCoins([...coins, data.markets[0]]);
} else if (data.markets.length <= 0) {
alert('coin not found');
}
if (hasSameCoin) {
alert('has same value');
}
}
});
console.log(coins, 'coins');
return (
<div>
<Card setCode={setCode} getData={getData} />
<CoinList loading={loading} coins={coins} setCoins={setCoins} setCode={setCode} />
</div>
);
};
export default App;
This is my Card component.
export const Card = ({ setCode, getData }: Props) => {
const [inputValue, setInputValue] = useState('');
const handleChange = (e: any) => {
setInputValue(e.target.value);
};
const onClick = () => {
if (inputValue) {
setCode(inputValue);
setInputValue('');
getData();
} else {
alert('enter a code please');
}
};
return (
<div className={styles.wrapper}>
<div>
<Input placeholder="BTC" value={inputValue} onChange={handleChange} />
</div>
<div>
<Button onClick={onClick}>Add</Button>
</div>
<div>
<div>Use of this service is subject to terms and conditions.</div>
</div>
</div>
)};
Here is my CoinList component.
export const CoinList = ({ loading, coins, setCoins }: Props) => {
if (loading) {
return <>Loading...</>;
}
const deleteCoin = (id: string) => {
const filteredCoins = coins.filter((c) => c.id !== id);
setCoins(filteredCoins);
};
return (
<>
{coins.map((coin, idx) => {
return (
<div className={styles.wrapper} key={`${coin.id}_${idx}`}>
<div>{coin.baseSymbol}</div>
<div>{coin.ticker.lastPrice.substring(0, 8)} €</div>
<div className={styles.delete} onClick={() => deleteCoin(coin.id)}>
<img src={deleteIcon} alt="deleteIcon" />
</div>
</div>
);
})}
</>
);
};
I fixed it when I added notifyOnNetworkStatusChange into options of useLazyQuery.
const [getData, { loading, data, error }] = useLazyQuery(GET_COIN_PRICE_QUERY, {
notifyOnNetworkStatusChange: true,
variables: { code },
fetchPolicy: 'network-only',
onCompleted: (data) => {
...
}
});