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 您的组件 开始 以确保您没有做任何愚蠢的事情,例如你现在是。

如果您的目标是根据全局 treeDataFilefilestree 组件派生 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>
  );
}