I'm trying to pass a state that is generated inside of an async function that itself is inside of a useState. I learned that useRef might be the best way to go about this since it can reference a mutable state, and in the process learned about react-useStateRef, which finally solved another issue I had of state never updating inside my main component (would constantly get "too many renders" errors). So it essentially acts as useRef and useState in one.
But while my state does finally update, it still doesn't pass to my Canvas component. I'm trying to update the BG graphic of the canvas depending on the temperature I get from my dataset.
import { useEffect } from 'react';
import useState from 'react-usestateref';
import { getServerData } from './serviceData';
import "./App.css"
import Canvas from './components/Canvas';
function App() {
const [dataset, setDataset] = useState(null);
const [units, setUnits] = useState('metric');
// canvas background graphic stuff
var [currentBG, setCurrentBG, currentBGref] = useState(null);
useEffect(() => {
const fetchServerData = async () => {
const data = await getServerData(city, units);
setDataset(data);
function updateBG() {
const threshold = units === "metric" ? 20 : 60;
if (data.temp <= threshold) {
setCurrentBG('snow');
}
else {
setCurrentBG('sunny');
}
}
updateBG();
}
fetchServerData();
console.log(currentBG)
}, [city, units, currentBGref.current, currentFGref.current])
const isCelsius = currentUnit === "C";
button.innerText = isCelsius ? "°F" : "°C";
setUnits(isCelsius ? "metric" : "imperial");
};
return (
<div className="app">
{ dataset && ( <Canvas width={640} height={480} currentBG={currentBGref.current}></Canvas> )}
</div>
);
}
export default App;
I can only pass the initial value and it never updates past that, although the console.log inside of the useEffect shows that it definitely is updating. So why isn't it passing to my component?
useStateRefappears to be an anti-pattern. You decide what the new state is so in the off-chance you need another reference to it, you can always create one yourself. I would suggest minimizing properties on your canvas to prevent unnecessary re-renders.Or maybe there's no reason to store the color as state. You could make your own
setColorfunction and attach it as an event listener -I would also suggest you look at SVG. I find the API gels with the React pattern much better than the Canvas API. The capabilities of each differ, but it's worth considering if SVG handles your needs.