Aden Lee
Aden Lee

Reputation: 260

How do I sustain data from DB while using another GET request with different query string in React(Next.js)?

I don't speak English very well. Please be understanding!

First, please check my code!


export default function DriveFolder() {

    const [clickFolderPk, setClickFolderPk] = useState(1);

    const viewFolder = async () => {
        const url = `/api/store/drive/view-folder?folderId=${clickFolderPk}`;
        await get(url)
            .then((res) => {
                console.log(res);
                setMainFolder(res.directChildrenFolders);
            })
            .catch((error) => {
                console.log(error);
            });
    };

    useEffect(() => {
        viewFolder();
    }, [clickFolderPk]);


    return (

        <div className={classes.driveFolder}>

            {mainFolder.map((main, key) => (
                <TreeView>
                    <TreeItem
                    onClick={() => setClickFolderPk(main.FOLDER_PK)}>
                        <TreeItem nodeId='10' label='OSS' />
                        <TreeItem nodeId='6' label='Material-UI'>
                            <TreeItem nodeId='7' label='src'>
                                <TreeItem nodeId='8' label='index.js' />
                                <TreeItem nodeId='9' label='tree-view.js' />
                            </TreeItem>
                        </TreeItem>
                    </TreeItem>
                </TreeView>
            ))}
        </div>
    );
}

I edited some code to make it clear. (might misspelled)

With this code, on the first rendering, since 'clickFolderPk' value is 1, I get the right data from DB.

However, since I have subfolders within folders from 'clickFolderPk' value 1, I have to request another GET REQUEST to see my subfolders from root folders.

Here is the simple image that you can understand my situation better.

first rendering

this is what I get from 'clickFolderPk' value 1.

However, when I press 'kikiki', GET request functions and render like this.

re render with different PK .

This is not the way I want to render things.

I want every data from DB, however they don't disappear whenever I use different GET request with different PK number.

I want them stay on the screen and get the subfolders within them.

I'm struggling with this issue for quite a time.

Your help will be really appreciated!!!!!

Upvotes: 0

Views: 28

Answers (1)

franznkemaka
franznkemaka

Reputation: 173

It's all about Nesting: Folders have sub-folders, etc and it goes on...

Note: To break things down, I will answer from a React point of view disregarding how your backend api is structured or returns data.

Basically there are two main approaches,

Approach #1:

The global state is a single source of truth for all the folders think of it like this:


  const [allFolders, setAllFolders] = useState([
    {
      id: "1",
      name: "a-1",
      folders: [
        {
          name: "a-subfolder-1",
          folders: [{ name: "a-subfolder-subfolder-1" }],
        },
        { name: "subfolder-2" },
      ],
    },
  ]);

The problem is that any small update requires to mutate the entire state. So I will focus more on Approach #2

Approach #2:

There is the main tree that has child components, child components can expand and have children too:

import { useEffect, useState } from "react";
import "./styles.css";

export default function DriveFolder() {
  const [folders, setFolders] = useState([
    { id: "1", name: "folder-a" },
    { id: "2", name: "folder-b" },
    { id: "3", name: "folder-c" }
  ]);

  return (
    <div style={{ display: "flex", flexDirection: "column" }}>
      {folders.map((folder) => {
        return <Folder key={folder.id} folder={folder} />;
      })}
    </div>
  );
}

const Folder = ({ parent = undefined, folder }) => {
  const [subfolders, setSubfolders] = useState([]);
  const [isOpened, setOpened] = useState(false);
  const hasSubfolders = subfolders.length > 0;

  useEffect(() => {
    // send request to your backend to fetch sub-folders

    // --------------- to ease stuff I will hard code it

    // with this you can limit the example of nest you wish
    const maxNestsCount = 5;
    const subfolderParent = parent || folder;
    const subfolder = {
      id: subfolderParent.id + "-sub",
      name: "subfolder-of-" + subfolderParent.name
    };
    const currentNestCount = subfolder.name.split("-sub").length;
    setSubfolders(currentNestCount < maxNestsCount ? [subfolder] : []);
    // -----------------------------
  }, []);

  const handleToggleShowSubFolders = (e) => {
    e.stopPropagation();
    if (!hasSubfolders) {
      return;
    }

    setOpened(!isOpened);
  };

  return (
    <div
      style={{
        display: "flex",
        flexDirection: "column",
        paddingHorizontal: 5,
        marginTop: 10,
        marginLeft: parent ? 20 : 0,
        backgroundColor: "#1678F230",
        cursor: hasSubfolders ? "pointer" : undefined
      }}
      onClick={handleToggleShowSubFolders}
    >
      {folder.name}

      <div style={{ display: isOpened ? "block" : "none" }}>
        {subfolders.map((subfolder) => (
          <Folder key={subfolder.id} parent={folder} folder={subfolder} />
        ))}
      </div>
    </div>
  );
};

Try it out:

Here is the output of the sample code above:

enter image description here

Upvotes: 1

Related Questions