1

Main Problem:

My local storage doesn't take an image.

I use this custom hook in my react.js project

import produce, { freeze } from "immer";
import { useCallback } from "react";
import useLocalStorageState from "use-local-storage-state";

export function useImmerLocalStorageState(key, options) {
  const [value, setValue] = useLocalStorageState(key, {
    ...options,
    defaultValue: freeze(options.defaultValue),
  });

  return [
    value,
    useCallback(
      (updater) => {
        if (typeof updater === "function") setValue(produce(updater));
        else setValue(freeze(updater));
      },
      [setValue]
    ),
  ];
}

I get this object logged out of the console for the state variable that should save the image.

{$$typeof: Symbol(react.element), type: {…}, key: null, ref: null, props: {…}, …}

I want that after voteCheckmarkImage is passed to the function with the local-storage-state and useImmer hook, it will be picked up from the local storage.

import { useRouter } from "next/router";
import styled from "styled-components";
import { useState } from "react";
import { StyledBackLink } from "@/components/styles/BackLink";
import VoteDetails from "@/components/VoteDetails";
import { voteIcons } from "@/Icons/dataIcons/";
import Image from "next/image";

function Votepage({ entryData, onHandleUpdateVoteEvent }) {
    const [voteCheckmarkImage, setVoteCheckmarkImage] = useState();
    const router = useRouter();
    const { id } = router.query;
    const currentEvent = entryData.find((entryToVote) => entryToVote.id === id);

    function handleVoteResult() {
        const resultVoteEvent = {
            ...currentEvent,
            voteResult: voteCheckmarkImage,
        };
        onHandleUpdateVoteEvent(resultVoteEvent);
    }

    return (
        <>
            <StyledMain>
                <StyledBackLink href="/">Home</StyledBackLink>

                <StyledVoteTitle>Voting</StyledVoteTitle>
                <StyledVoteEventCard>
                    <VoteDetails
                        voteCheckmarkImage={voteCheckmarkImage}
                        currentEvent={currentEvent}
                    />

                    <StyledEmojiCheckmark>{voteCheckmarkImage}</StyledEmojiCheckmark>
                </StyledVoteEventCard>

                <StyledVoteButtonContainer>
                    {voteIcons.map((voteIcon) => (
                        <StyledVoteButtons
                            key={voteIcon.id}
                            onClick={() =>
                                setVoteCheckmarkImage(
                                    <Image
                                        width={50}
                                        height={50}
                                        src={voteIcon.imageSrc}
                                        alt={voteIcon.description}
                                    />
                                )
                            }
                        >
                            <Image
                                width={80}
                                height={80}
                                src={voteIcon.imageSrc}
                                alt={voteIcon.description}
                            />
                        </StyledVoteButtons>
                    ))}
                </StyledVoteButtonContainer>

                <StyledButtonConfirm type="button" onClick={handleVoteResult}>
                    Confirm
                </StyledButtonConfirm>
            </StyledMain>
        </>
    );
}

to...

import GlobalStyle from "@/styles";
import Head from "next/head";
import { v4 as uuidv4 } from "uuid";
import { useImmerLocalStorageState } from "@/lib/hooks";

export default function App({ Component, pageProps }) {
    const [entryData, setEntryData] = useImmerLocalStorageState("entryData", {
        defaultValue: [],
    });
    console.log(entryData);
    function handleEntryData(data) {
        const newData = { ...data, id: uuidv4() };

        setEntryData([newData, ...entryData]);
    }

    function handleUpdateVoteEvent(resultVoteEvent) {
        console.log(resultVoteEvent);
        setEntryData((draft) => {
            const votedEvent = draft.find(
                (voteEvent) => voteEvent.id === resultVoteEvent.id
            );
            votedEvent.voteResult = resultVoteEvent.voteResult;
        });
    }

    return (
        <>
            <GlobalStyle />
            <Head>
                <title>Capstone Project</title>
            </Head>
            <main>
                <Component
                    {...pageProps}
                    entryData={entryData}
                    onHandleEntryData={handleEntryData}
                    onHandleUpdateVoteEvent={handleUpdateVoteEvent}
                />
            </main>
        </>
    );
}

I have tried voteCheckmarkImage with a String instead and works. but neither addressed the src and alt attributes with voteCheckmarkImag.props, nor did the destructuring bring me to my goal.

hossi
  • 23
  • 4
  • `window.localStorage` is not intended for storing binary data - [you should use OPFS instead](https://stackoverflow.com/a/71581910/159145). – Dai May 04 '23 at 06:58
  • Thank you for your answer, the hint and the link. I'll read through that. That gets me further :) – hossi May 04 '23 at 07:15

0 Answers0