DEV Community

Ateev Duggal
Ateev Duggal

Posted on

Trouble accessing context values with useContext in child component

I am making Google Keep Clone with React and Context API (useContext hook). It was going very smoothly, everything was coming in proper order until I thought of somehow passing the notes from home to the archive and delete section using a button. For this purpose, I have used useContext hook so that I can avoid unnecessary prop drilling and complex codes. But somehow it's not working. Can anyone help me?

import React, { createContext, useState } from "react";
export const dataContext = createContext([]);

const Context = ({ children }) => {
  const [addData, setAddData] = useState([]); //to store all the values of the state data
  const [archive, setArchive] = useState([]);
  const [deleteNotes, setDeleteNotes] = useState([]);

  return (
    <>
      <dataContext.Provider
        value={{
          addData,
          setAddData,
          archive,
          setArchive,
          deleteNotes,
          setDeleteNotes,
        }}
      >
        {children}
      </dataContext.Provider>
    </>
  );
};

export default Context;
// export { dataContext };
Enter fullscreen mode Exit fullscreen mode
import React, { useContext, useState } from "react";
import Inputbox from "../Components/Inputbox";
import { dataContext } from "../Components/Context";
import { v4 as uuid } from "uuid";
import SingleNote from "../Components/SingleNote";

const Notes = () => {
  const [loading, setLoading] = useState(true);
  const { addData, setAddData, setArchive, setDeleteNotes } =
    useContext(dataContext);
  //Math.random can also be used here but to make things simpler we have used a npm package as we don't know how many notes will a person will save
  const [show, setShow] = useState(false); //to toggle between between the main note and the big note

  const [data, setData] = useState({
    //to stores all the values given by the user
    id: uuid(),
    title: "",
    description: "",
  });

  const addNote = () => {
    setAddData((oldData) => {
      return [...oldData, data]; // Calling the done function using the addNote function
    });
  };

  const Delete = (index) => {
    const DelArray = addData.filter((Val) => {
      return index !== Val.id;
    });
    setAddData(DelArray);
    setDeleteNotes((preArr) => [addData, ...preArr]);
  };

  const Archive = (index) => {
    const ArchiveArray = addData.filter((Val) => {
      return index !== Val.id;
    });
    setAddData(ArchiveArray);
    setArchive((preArr) => [addData, ...preArr]);
  };

  const handleClickAway = (e, val) => {
    e.preventDefault();
    setShow(false); //if data filed is blank, close the input fields
    //if data field is not empty
    if (data.title || data.description) {
      setLoading(false);
      addNote(val);
      setData({
        title: "",
        description: "",
      });
    }
  };
  return (
    <>
      <Inputbox
        handleClickAway={handleClickAway}
        data={data}
        setData={setData}
        setAddData={setAddData}
        show={show}
        setShow={setShow}
      />
      {loading ? (
        <div style={{ marginLeft: "30%", marginTop: "5%" }}>
          <div className="icon-1">
            <i class="fa-regular fa-note-sticky"></i>
          </div>
          <div className="fs-3 fw-bold opacity-50">
            Your Notes will Appear Here
          </div>
        </div>
      ) : (
        <SingleNote addData={addData} Delete={Delete} Archive={Archive} />
      )}
    </>
  );
};

export default Notes;
Enter fullscreen mode Exit fullscreen mode
import React from "react";

const SingleNote = ({ addData, Delete, Archive }) => {
  return (
    <>
      <div className="row mt-5 d-flex">
        {addData &&
          addData.map((Val, index) => {
            const { title, description, id } = Val;
            return (
              <>
                <div className="note m-3" key={index} id={index}>
                  <div className="fs-4 fw-bold">{title}</div>
                  <br />
                  <p>{description}</p>
                  <div className="d-flex flex-row-reverse">
                    <div
                      onClick={() => Delete(id)}
                      style={{ cursor: "pointer" }}
                      title="Delete"
                    >
                      <i className="fa-regular fa-trash-can fs-4 py-2 text-danger mx-3"></i>
                    </div>
                    <div
                      onClick={() => Archive(id)}
                      style={{ cursor: "pointer" }}
                      title="Archive"
                    >
                      <i className="fa-solid fa-boxes-stacked fs-4 py-2 text-success"></i>
                    </div>
                  </div>
                </div>
              </>
            );
          })}
      </div>
    </>
  );
};

export default SingleNote;
Enter fullscreen mode Exit fullscreen mode
import React, { useContext } from "react";
import { dataContext } from "../Components/Context";

const Archive = () => {
  const { archive, setAddData, setArchive, setDeleteNotes } =
    useContext(dataContext);

  const Delete = (index) => {
    const DelArray = archive[0].filter((Val) => {
      return index !== Val.id;
    });
    setDeleteNotes(DelArray);
    setAddData((preArr) => [archive, ...preArr]);
  };

  const UnArchive = (index) => {
    const ArchiveArray = archive[0].filter((Val) => {
      return Val.id !== index;
    });
    setArchive(ArchiveArray);
    setAddData((preArr) => [...preArr, archive]);
  };
  return (
    <>
      <div className="row mt-5 d-flex">
        {archive.map((Val, index) => {
          const entry = Val[0];
          const { title, description, id } = entry;
          return (
            <>
              <div className="note m-3" key={index} id={index}>
                <div className="fs-4 fw-bold">{title}</div>
                <br />
                <p>{description}</p>
                <div className="d-flex flex-row-reverse">
                  <div
                    onClick={() => Delete(id)}
                    style={{ cursor: "pointer" }}
                    title="Delete"
                  >
                    <i className="fa-regular fa-trash-can fs-4 py-2 text-danger mx-3"></i>
                  </div>
                  <div
                    onClick={() => UnArchive(id)}
                    style={{ cursor: "pointer" }}
                    title="Unarchive"
                  >
                    <i className="fa-solid fa-arrow-up-from-ground-water fs-4 py-2 text-success"></i>
                  </div>
                </div>
              </div>
            </>
          );
        })}
      </div>
    </>
  );
};

export default Archive;
Enter fullscreen mode Exit fullscreen mode

Now the problem that I am facing is I can send the data from the notes component to the archive component, but it's not coming back from the archive component to the notes component. PLease help me.

Top comments (0)