When pushing data into a file tree, it pushes 2 sets of the same data and I am not exactly sure why.
I have a simple json array that looks like this:
export const treeDataFile = [{
type: 'directory',
name: '2022',
}]
export default treeDataFile;
I am trying to push 4 files I have into it like this by calling this function:
const addFileToTree = (file,i) => {
treeDataFile.push({type: i, name: file});
console.log(treeDataFile)
setFirstRender(true);
};
This is how addFileToTree is being called:
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>
);
};
The result has been this, there should only be 4 items, but it has duplicated it.
Any help would be greatly appreciated.
You're mutating the global
treeDataFile
as a side effect of your component function (and even "worse", as a side effect of a render.map()
). Among other things, this would causetreeDataFile
to grow larger and larger every time your component is updated.You're also probably using React's StrictMode, which double-renders your components to begin with to make sure you're not doing anything silly, like you now are.
If your goal is to derive a
treeDataFile
for thattree
component based on the globaltreeDataFile
andfiles
, you can do that withuseMemo
, which is a hook designed for deriving new data based on other data; in this case your "base"treeDataFile
and thefiles
you get. (I assume they're props, since you don't show. They could be state, too, of course.)I elided the table from this component, since it didn't have any real content based on the original code you had.
EDIT: Based on the augmented code in the question, the expected types for everything become a bit clearer. For one, it's now clear
files
is an array of AWS Amplify S3 files, and that we're using Geist's Tree component. A full, working example in TypeScript (without AWS Amplify, but with its types) can be found in this CodeSandbox.