ReactJS和Material UI树视图:我可以使用JSON/对象数组来填充树视图吗?
我有一个对象数组,其中包含需要填充ReactJS和Material UI树视图:我可以使用JSON/对象数组来填充树视图吗?,json,reactjs,treeview,material-ui,Json,Reactjs,Treeview,Material Ui,我有一个对象数组,其中包含需要填充组件的值: const treeItems = [ { id: uuidv4(), name: 'English', children: [ { id: uuidv4(), name: 'Spring', children: [] } ] }
组件的值:
const treeItems = [
{
id: uuidv4(),
name: 'English',
children: [
{
id: uuidv4(),
name: 'Spring',
children: []
}
]
},
{
id: uuidv4(),
name: 'Italian',
children: [
{
id: uuidv4(),
name: 'Level A',
children: []
}
]
}
]
我想用它作为一个道具,用TreeItems
自动填充TreeView
目前,我有一个函数,可以在传递数组时呈现子对象,但是检查文档()时,我注意到有一个用于子对象的道具
子节点是组件的内容
是否可以使用JSON/array of object来填充TreeView?TreeView组件没有任何内置功能,但是创建可重用代码来为给定数据结构提供此功能非常简单 以下是一种方法:
import React from "react";
import ReactDOM from "react-dom";
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 { sampleFromStackOverflowQuestion, seasons } from "./sampleData";
const getTreeItemsFromData = treeItems => {
return treeItems.map(treeItemData => {
let children = undefined;
if (treeItemData.children && treeItemData.children.length > 0) {
children = getTreeItemsFromData(treeItemData.children);
}
return (
<TreeItem
key={treeItemData.id}
nodeId={treeItemData.id}
label={treeItemData.name}
children={children}
/>
);
});
};
const DataTreeView = ({ treeItems }) => {
return (
<TreeView
defaultCollapseIcon={<ExpandMoreIcon />}
defaultExpandIcon={<ChevronRightIcon />}
>
{getTreeItemsFromData(treeItems)}
</TreeView>
);
};
function App() {
return (
<div className="App">
<DataTreeView treeItems={sampleFromStackOverflowQuestion} />
<br />
<DataTreeView treeItems={seasons} />
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
以下是物料界面文档中提到的另一种方式
import React from 'react';
import { makeStyles } from '@material-ui/core/styles';
import TreeView from '@material-ui/lab/TreeView';
import ExpandMoreIcon from '@material-ui/icons/ExpandMore';
import ChevronRightIcon from '@material-ui/icons/ChevronRight';
import TreeItem from '@material-ui/lab/TreeItem';
import _ from 'lodash';
const useStyles = makeStyles({
root: {
height: 216,
flexGrow: 1,
maxWidth: 400,
},
});
export default function ControlledTreeView(props) {
const classes = useStyles();
const [expanded, setExpanded] = React.useState([]);
const [selected, setSelected] = React.useState([]);
const [searchValue, setSearchValue] = React.useState('');
const [stateData, setStateData] = React.useState([]);
React.useEffect(
() => {
const { data } = props;
setStateData(data);
},
[props],
);
const handleToggle = (event, nodeIds) => {
setExpanded(nodeIds);
};
const handleSelect = (event, nodeIds) => {
setSelected(nodeIds);
};
const onSearch = (search) => {
setSearchValue(search);
console.log(searchTree(search, props.data));
};
function searchTree(str, data) {
const searchStr = str.toLowerCase();
// Only return the entries that contain a matched value
return _.filter(data, (datum) => {
// Check if name matches
return _.includes(datum.name, searchStr)
|| _.some(datum.activities, (activity) => {
return _.entries(activity.routines).some(([routine, {details}]) => {
// Check if dynamic routine matches or details
return _.includes(routine, searchStr) || _.includes(details, searchStr);
});
});
});
};
const renderTree = (nodes) => (
<TreeItem key={nodes.id} nodeId={nodes.id} label={nodes.name}>
{Array.isArray(nodes.children) ? nodes.children.map((node) => renderTree(node)) : null}
</TreeItem>
);
return (
<div>
<TreeView
className={classes.root}
defaultCollapseIcon={<ExpandMoreIcon />}
defaultExpanded={['root']}
defaultExpandIcon={<ChevronRightIcon />}
>
{renderTree(stateData)}
</TreeView>
</div>
);
}
子组件
是您包装在其中的子组件。要使用数组的内容,您必须将其映射到上面,这就是我现在正在做的。事实上,我发现RSUITE 3有一个树组件,允许传递JSON来填充它(),这正是我所需要的。我想你可以选择使用另一个库来填充你的应用程序,或者只是使用编码来继续使用你应用程序中其他地方可能已经有的材质ui。我想这是您想要继续使用的开发环境设置/选择。我不会混合使用这两个库。由于我处于开发的早期阶段,切换会很快完成。我不知道TreeView
不接受项。但我想它会尝试将所有的显示层作为子层
。如果是这样的话,那么这个答案对我来说是非常可靠的。我们如何用typescript转换它呢?。。它给了我一个错误“Binding元素'treeItems'隐式地在const DataTreeView=({treeItems})附近有一个'any'类型”@DhawalMhatre抱歉,但我个人并不使用Typescript,所以我无法帮助你提供如何向其中添加适当类型的建议。@DhawalMhatre我今天开始学习一些Typescript,所以我添加了一个Typescript版本。这只在嵌套元素具有相同属性时才有效
import React from 'react';
import { makeStyles } from '@material-ui/core/styles';
import TreeView from '@material-ui/lab/TreeView';
import ExpandMoreIcon from '@material-ui/icons/ExpandMore';
import ChevronRightIcon from '@material-ui/icons/ChevronRight';
import TreeItem from '@material-ui/lab/TreeItem';
import _ from 'lodash';
const useStyles = makeStyles({
root: {
height: 216,
flexGrow: 1,
maxWidth: 400,
},
});
export default function ControlledTreeView(props) {
const classes = useStyles();
const [expanded, setExpanded] = React.useState([]);
const [selected, setSelected] = React.useState([]);
const [searchValue, setSearchValue] = React.useState('');
const [stateData, setStateData] = React.useState([]);
React.useEffect(
() => {
const { data } = props;
setStateData(data);
},
[props],
);
const handleToggle = (event, nodeIds) => {
setExpanded(nodeIds);
};
const handleSelect = (event, nodeIds) => {
setSelected(nodeIds);
};
const onSearch = (search) => {
setSearchValue(search);
console.log(searchTree(search, props.data));
};
function searchTree(str, data) {
const searchStr = str.toLowerCase();
// Only return the entries that contain a matched value
return _.filter(data, (datum) => {
// Check if name matches
return _.includes(datum.name, searchStr)
|| _.some(datum.activities, (activity) => {
return _.entries(activity.routines).some(([routine, {details}]) => {
// Check if dynamic routine matches or details
return _.includes(routine, searchStr) || _.includes(details, searchStr);
});
});
});
};
const renderTree = (nodes) => (
<TreeItem key={nodes.id} nodeId={nodes.id} label={nodes.name}>
{Array.isArray(nodes.children) ? nodes.children.map((node) => renderTree(node)) : null}
</TreeItem>
);
return (
<div>
<TreeView
className={classes.root}
defaultCollapseIcon={<ExpandMoreIcon />}
defaultExpanded={['root']}
defaultExpandIcon={<ChevronRightIcon />}
>
{renderTree(stateData)}
</TreeView>
</div>
);
}
const TreeViewData = {
id: 'root',
name: 'Documents',
children: [
{
id: '1',
name: 'Report',
children: [
{
id: '2',
name: 'PDF',
},
],
},
{
id: '3',
name: 'Files',
children: [
{
id: '4',
name: 'Excel',
},
],
},
{
id: '5',
name: 'Programs',
children: [
{
id: '6',
name: 'Codes',
},
{
id: '7',
name: 'Data',
},
],
},
],
};