Estoy tratando de construir un algoritmo de factorización usando reaccionar. Me gustaría agregar results a LocalStorage en función de los resultados de la factorización . Sin embargo, LocalStorage establece los resultados anteriores, no los actuales.
Creo que esto sucede porque useEffect se ejecuta en cada nuevo [number] (= entrada del usuario) y no se basa en [results] . Sin embargo, necesito useEffect para ejecutar el nuevo envío de entrada de usuario porque es cuando se debe activar la factorización.
¿Cómo podría hacer que localStorage establezca los resultados correctos después de que se haya completado la factorización (en el finally final si es posible)?
const [results, setResults] = useState({ default: [], detailed: [], isPrime: '', }); const { number } = props useEffect(() => { handleWorker(number); //accessing results here will give previous results }, [number]); const handleWorker = number => { try { const worker = new Worker(new URL('facto.js', import.meta.url)); worker.postMessage({ number, algorithm }); worker.onmessage = ({ data: { facto } }) => { setResults({ ...facto }); //the worker 'streams live' results and updates them on setResults }; } catch(error) { console.log(error.message) } finally { localStorage.setItem(number, results) //here, results is not current state but previous one } };Tenga en cuenta que todo lo demás funciona bien
Gracias
Obtiene el valor anterior porque localStorage.setItem se ejecuta antes setResults actualice el estado. Puedes hacer un refactor para que funcione:
const [results, setResults] = useState({ default: [], detailed: [], isPrime: '', }); const { number } = props; const workerRef = useRef(new Worker(new URL('facto.js', import.meta.url))); const worker = workerRef.current; useEffect(()=> { //-> create the listener just once worker.onmessage = ({ data: { facto } }) => { setResults({ ...facto }); }; }, []); useEffect(() => { //-> send message if number changed worker.postMessage({ number, algorithm }); }, [number]); useEffect(() => { //-> update localStorage if results changed localStorage.setItem(number, results) }, [results]);Esto es lo que necesita (probablemente):
const [results, setResults] = useState({ /* YOUR STATE */ }); const { number } = props const handleWorker = useCallback((number) => { // DO WHATEVER YOU NEED TO DO HERE },[]); // IF YOU DEPEND ON ANY MUTABLE VARIABLES, ADD THEM TO THE DEPENDENCY ARRAY useEffect(() => { // DO WHATEVER YOU NEED TO DO HERE // INSTEAD OF localStorage.setItem(number, results) // DO localStorage.setItem(number, { ...facto }) }, [number,handleWorker]);Déjame saber si funciona.
Creo que puede pasar el estado del resultado como dependiente para useEffect, por lo que cada vez que cambie el valor del resultado, useEffect se ejecuta
useEffect(() => { //code goes here}, [results]);Digamos que los resultados también dependen de una función handleWorker
useEffect(() => { //code goes here}, [results,handleWorker]);