Json 数组使用 React 将数据两次推送到文件树
Json Array Pushes Data Twice to File Tree with React
将数据推送到文件树时,它会推送 2 组相同的数据,我不确定为什么。
我有一个简单的 json 数组,如下所示:
export const treeDataFile = [{
type: 'directory',
name: '2022',
}]
export default treeDataFile;
我正在尝试通过调用此函数将我拥有的 4 个文件推送到其中:
const addFileToTree = (file,i) => {
treeDataFile.push({type: i, name: file});
console.log(treeDataFile)
setFirstRender(true);
};
调用 addFileToTree 的方式如下:
const [files, setFiles] = useState([]);
//AWS Setup
useEffect(() => {
Amplify.configure({
Auth:{
identityPoolId: '',
region: 'us-east-1',
},
Storage: {
AWSS3: {
bucket:'',
region: 'ca-central-1',
}
}
});
},[]);
//gets all files in the bucket
useEffect(() => {
Storage.list('').then(files => {
const s3_files = setFiles(files);
s3_files.replace("\"eTag\":", "\"perfect\":");
console.log(s3_files);
}).catch(err => {
console.log(err);
});
},[]);
return (
<div classname="container">
<GeistProvider>
<CssBaseline />
<Tree style={{width:"280px", height: "500"}} value={treeDataFile} onClick={handleShow} />
</GeistProvider>
<table>
<tbody>
{files.map((file,i) => (
<tr key={file.key}>
{addFileToTree(file.key,i)}
</tr>
))}
</tbody>
</table>
</div>
);
};
结果是这样的,应该只有4条,结果重复了
如有任何帮助,我们将不胜感激。
你正在改变全局 treeDataFile
作为组件函数的副作用(甚至“更糟”,作为渲染 .map()
的副作用)。除其他外,这会导致 treeDataFile
每次更新组件时变得越来越大。
您可能还在使用 React's StrictMode,double-renders 您的组件 开始 以确保您没有做任何愚蠢的事情,例如你现在是。
如果您的目标是根据全局 treeDataFile
和 files
为 tree
组件派生 treeDataFile
,您可以使用 useMemo
,这是一个钩子,用于根据其他数据派生新数据;在这种情况下,您的“基础”treeDataFile
和您得到的 files
。 (我假设它们是道具,因为你没有展示。它们当然也可以是状态。)
我从该组件中删除了 table,因为它没有任何基于您的原始代码的实际内容。
编辑: 根据问题中的扩充代码,所有内容的预期类型都变得更加清晰。首先,现在很清楚 files
是一组 AWS Amplify S3 文件,并且我们正在使用 Geist 的树组件。 A full, working example in TypeScript (without AWS Amplify, but with its types) can be found in this CodeSandbox.
const treeDataFile = [{
type: "directory",
name: '2022',
}];
export default function App() {
const [files, setFiles] = React.useState([]);
React.useEffect(() => {
// Load files via AWS Amplify.
Storage.list('').then(setFiles);
}, []);
const treeWithFiles = React.useMemo(() => {
const tree = [...treeDataFiles]; // shallow-copy
(files || []).forEach((file, i) => {
tree.push({ type: "file", name: String(file.key) });
});
return tree;
}, [files]);
return (
<div className="container">
<GeistProvider>
<CssBaseline />
<Tree style={{ width: "280px", height: "500" }} value={treeWithFiles} />
</GeistProvider>
</div>
);
}
将数据推送到文件树时,它会推送 2 组相同的数据,我不确定为什么。
我有一个简单的 json 数组,如下所示:
export const treeDataFile = [{
type: 'directory',
name: '2022',
}]
export default treeDataFile;
我正在尝试通过调用此函数将我拥有的 4 个文件推送到其中:
const addFileToTree = (file,i) => {
treeDataFile.push({type: i, name: file});
console.log(treeDataFile)
setFirstRender(true);
};
调用 addFileToTree 的方式如下:
const [files, setFiles] = useState([]);
//AWS Setup
useEffect(() => {
Amplify.configure({
Auth:{
identityPoolId: '',
region: 'us-east-1',
},
Storage: {
AWSS3: {
bucket:'',
region: 'ca-central-1',
}
}
});
},[]);
//gets all files in the bucket
useEffect(() => {
Storage.list('').then(files => {
const s3_files = setFiles(files);
s3_files.replace("\"eTag\":", "\"perfect\":");
console.log(s3_files);
}).catch(err => {
console.log(err);
});
},[]);
return (
<div classname="container">
<GeistProvider>
<CssBaseline />
<Tree style={{width:"280px", height: "500"}} value={treeDataFile} onClick={handleShow} />
</GeistProvider>
<table>
<tbody>
{files.map((file,i) => (
<tr key={file.key}>
{addFileToTree(file.key,i)}
</tr>
))}
</tbody>
</table>
</div>
);
};
结果是这样的,应该只有4条,结果重复了
如有任何帮助,我们将不胜感激。
你正在改变全局 treeDataFile
作为组件函数的副作用(甚至“更糟”,作为渲染 .map()
的副作用)。除其他外,这会导致 treeDataFile
每次更新组件时变得越来越大。
您可能还在使用 React's StrictMode,double-renders 您的组件 开始 以确保您没有做任何愚蠢的事情,例如你现在是。
如果您的目标是根据全局 treeDataFile
和 files
为 tree
组件派生 treeDataFile
,您可以使用 useMemo
,这是一个钩子,用于根据其他数据派生新数据;在这种情况下,您的“基础”treeDataFile
和您得到的 files
。 (我假设它们是道具,因为你没有展示。它们当然也可以是状态。)
我从该组件中删除了 table,因为它没有任何基于您的原始代码的实际内容。
编辑: 根据问题中的扩充代码,所有内容的预期类型都变得更加清晰。首先,现在很清楚 files
是一组 AWS Amplify S3 文件,并且我们正在使用 Geist 的树组件。 A full, working example in TypeScript (without AWS Amplify, but with its types) can be found in this CodeSandbox.
const treeDataFile = [{
type: "directory",
name: '2022',
}];
export default function App() {
const [files, setFiles] = React.useState([]);
React.useEffect(() => {
// Load files via AWS Amplify.
Storage.list('').then(setFiles);
}, []);
const treeWithFiles = React.useMemo(() => {
const tree = [...treeDataFiles]; // shallow-copy
(files || []).forEach((file, i) => {
tree.push({ type: "file", name: String(file.key) });
});
return tree;
}, [files]);
return (
<div className="container">
<GeistProvider>
<CssBaseline />
<Tree style={{ width: "280px", height: "500" }} value={treeWithFiles} />
</GeistProvider>
</div>
);
}