【问题标题】:Material-UI TreeView component does not re-render on adding childrenMaterial-UI TreeView 组件在添加子项时不会重新渲染
【发布时间】:2021-09-09 02:40:18
【问题描述】:

我已经坚持了很长时间。我正在使用 Material-UI 的 TreeView 组件来显示一个目录列表,我在其中嵌套了文档。当我添加新目录(或文档)时,组件需要刷新才能显示新目录。我觉得我已经尝试了 useEffect 和 useState 的每一种排列来实现这一点,我现在很困惑。

import React, { useState, useEffect } from "react";
import { useHistory } from "react-router-dom";
import axios from "axios";
import { makeStyles } from "@material-ui/core/styles";
import TreeView from "@material-ui/lab/TreeView";
import TreeItem from "@material-ui/lab/TreeItem";
import ExpandMoreIcon from "@material-ui/icons/ExpandMore";
import ChevronRightIcon from "@material-ui/icons/ChevronRight";
import "./styles/Directories.css";

const Directories = () => {
    const [root, setRoot] = useState([]);
    const [showForm, setShowForm] = useState(false);
    const [directories, setDirectories] = useState([]);
    const [parentDirectory, setParentDirectory] = useState("");
    const [directoryName, setDirectoryName] = useState("");
    const [documents, setDocuments] = useState([]);
    const history = useHistory();

    useEffect(() => {
        (async () => {
            const res = await axios.get("/api/directories/");
            const rootDirectory = res.data.root;
            setRoot(rootDirectory);
        })();
    }, []);

    useEffect(() => {
        (async () => {
            const res = await axios.get("/api/directories/all");
            const directoriesArray = res.data.directories;
            setDirectories(directoriesArray);
            setParentDirectory(directoriesArray[0].id);
        })();
    }, []);

    useEffect(() => {
        (async () => {
            const res = await axios.get("/api/documents/");
            setDocuments(res.data.documents);
        })();
    }, []);

    const parentDirectoryChange = (e) => {
        setParentDirectory(e.target.value);
    };

    const directoryNameChange = (e) => {
        setDirectoryName(e.target.value);
    };

    const addDirectory = async (e) => {
        e.preventDefault();

        const response = await axios.post("/api/directories/", {
            "parent-directory": parentDirectory,
            "directory-name": directoryName,
        });

        if (response.ok) {
            const data = await axios.get("/api/directories/all");
            const newDirectories = data.data.directories
            setDirectories(newDirectories)
        }

    };

    const useStyles = makeStyles({
        root: {
            height: 110,
            flexGrow: 1,
            maxWidth: 400,
        },
    });

    const classes = useStyles();

    // <TreeItem
    //      key={document.id}
    //      nodeId={document.id}
    //      label={document.name}
    //  />

    const renderTree = (root) => (
        <TreeItem key={root.id} nodeId={root.name} label={root.name}>
            {Array.isArray(root.children)
                ? root.children.map((directory) => renderTree(directory))
                : null}
            {documents
                .filter((document) => document.directory_id === root.id)
                .map((document) => (
                    <TreeItem
                        key={document.id}
                        nodeId={`${root.id}-${document.id}`}
                        label={document.title}
                        onClick={() => history.push(`documents/${document.id}`)}
                    />
                ))}
        </TreeItem>
    );

    return (
        <div className="page-wrapper">
            <div className="header-wrapper">
                <h1 className="directories-header">Directories</h1>
            </div>
            <div>
                <button
                    type="submit"
                    className="buttons"
                    onClick={() => setShowForm(!showForm)}
                >
                    Add New Directory
                </button>
                {showForm ? (
                    <form onSubmit={addDirectory} className="new-directory-form">
                        <div className="inputs-wrapper">
                            <label>Parent Directory</label>
                            <select
                                name="parent-directory"
                                onChange={parentDirectoryChange}
                                value={parentDirectory}
                                required
                            >
                                {directories.map((directory) => (
                                    <option key={directory.id} value={directory.id}>{directory.name}</option>
                                ))}
                            </select>

                            <label>Directory Name</label>
                            <input
                                type="text"
                                name="directory-name"
                                onChange={directoryNameChange}
                                required
                            />
                        </div>
                        <button type="submit" className="buttons">
                            Add Directory
                        </button>
                    </form>
                ) : null}
            </div>
            <div>
                <TreeView
                    className={classes.root}
                    defaultCollapseIcon={<ExpandMoreIcon />}
                    defaultExpanded={["root"]}
                    defaultExpandIcon={<ChevronRightIcon />}
                >
                    {renderTree(root)}
                </TreeView>
            </div>
        </div>
    );
};

【问题讨论】:

    标签: reactjs react-hooks material-ui


    【解决方案1】:

    我得到了这个工作。由于我的 renderTree 函数使用我的根目录为我的每个目录递归渲染 TreeView,我需要在我的点击处理程序中调用 setRoot 而不是 setDirectories。这是更新的点击处理程序:

    const addDirectory = async (e) => {
        e.preventDefault();
    
        await axios.post("/api/directories/", {
            "parent-directory": parentDirectory,
            "directory-name": directoryName,
        });
    
        const res = await axios.get("/api/directories/");
        const newRoot = res.data.root;
        setRoot(newRoot)
    
    };
    

    【讨论】:

      猜你喜欢
      • 2020-02-13
      • 2020-04-18
      • 2018-08-12
      • 2019-06-01
      • 1970-01-01
      • 2021-09-17
      • 2017-05-31
      • 2019-11-26
      • 1970-01-01
      相关资源
      最近更新 更多