I have multiple react projects and a package - react-core. I put there everything which is duplicated in all projects. So In a project I have a Datatable and ActiveFilters component, which is:
import React, { useEffect } from 'react';
import { Chip, Box } from '@mui/material';
import { useSearchParams } from 'react-router-dom';
export const useSetFiltersFromQuery = (defaultFilters) => {
const [searchParams] = useSearchParams();
const initialFilters = { ...defaultFilters };
Object.entries(defaultFilters).forEach(([key, defaultValue]) => {
const paramValue = searchParams.get(key);
if (paramValue) {
// Initialize filter state based on query param
initialFilters[key] = Array.isArray(defaultValue) ? paramValue.split(',') : paramValue;
}
});
return initialFilters;
};
export const ActiveFilters = ({
filters,
filtersSetter,
defaultFilters,
filterLabels
}) => {
const [searchParams, setSearchParams] = useSearchParams();
useEffect(() => {
const params = {};
Object.entries(filters).forEach(([key, value]) => {
if (value && (Array.isArray(value) ? value.length > 0 : true)) {
params[key] = Array.isArray(value) ? value.join(',') : value;
}
});
setSearchParams(params); // Sync with query params
}, [filters, setSearchParams]);
const handleRemoveFilter = (filterName) => {
const newFilters = { ...filters, [filterName]: defaultFilters[filterName] };
filtersSetter(newFilters); // Update the filter state in parent
const params = new URLSearchParams(searchParams);
if (defaultFilters[filterName] === '' || defaultFilters[filterName].length === 0) {
params.delete(filterName);
} else {
params.set(filterName, defaultFilters[filterName]);
}
setSearchParams(params); // Update the query params
};
return (
<Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 1 }}>
{Object.entries(filters).map(([key, value]) => {
if (value && (Array.isArray(value) ? value.length > 0 : true)) {
return (
<Chip
key={key}
label={`${filterLabels[key]}: ${Array.isArray(value) ? value.join(', ') : value}`}
onDelete={() => handleRemoveFilter(key)}
/>
);
}
return null;
})}
</Box>
);
};
I call it from a parent component (where the table is located) like this:
import { DataTable, FilterButton, ActiveFilters, useSetFiltersFromQuery } from 'react-core/dist/components';
const ParentComponent = () => {
const defaultFilters = {
id: '',
category: '',
status: [],
};
const initialFilters = useSetFiltersFromQuery(defaultFilters);
// Initialize state with the result of the hook
const [filters, setFilters] = useState(initialFilters);
// ... some stuff about datatables
return (
...
<ActiveFilters filters={filters} filtersSetter={setFilters} defaultFilters={defaultFilters} filterLabels={filterLabels}/>
)}
Now the main part: It works when both components are IN THE SAME project. When I move ActiveFilters out of the project and put in the package, I get these errors:
components.js:184 Uncaught Error
at xe (components.js:184:1)
at ze (components.js:184:1)
at Je (components.js:184:1)
at at (components.js:184:1)
at ParentComponent (ParentComponent.jsx:42:1)
at renderWithHooks (react-dom.development.js:15486:1)
at mountIndeterminateComponent (react-dom.development.js:20103:1)
at beginWork (react-dom.development.js:21626:1)
at HTMLUnknownElement.callCallback (react-dom.development.js:4164:1)
at Object.invokeGuardedCallbackDev (react-dom.development.js:4213:1)
The above error occurred in the <ParentComponent> component:
at ParentComponent (http://localhost:3000/static/js/bundle.js:1012:115)
at RenderedRoute (http://localhost:3000/static/js/bundle.js:211695:5)
at Routes (http://localhost:3000/static/js/bundle.js:212429:5)
at AppRouter
at main
at http://localhost:3000/static/js/bundle.js:139632:66
at Box (http://localhost:3000/static/js/bundle.js:163480:81)
at u (http://localhost:3000/static/js/bundle.js:57727:23)
at x (http://localhost:3000/static/js/bundle.js:57808:23)
at DefaultPropsProvider (http://localhost:3000/static/js/bundle.js:162159:3)
at RtlProvider (http://localhost:3000/static/js/bundle.js:162399:3)
at ThemeProvider (http://localhost:3000/static/js/bundle.js:161809:5)
at ThemeProvider (http://localhost:3000/static/js/bundle.js:162690:5)
at ThemeProviderNoVars (http://localhost:3000/static/js/bundle.js:158297:10)
at ThemeProvider (http://localhost:3000/static/js/bundle.js:158250:3)
at Layout (http://localhost:3000/static/js/bundle.js:49:82)
at Router (http://localhost:3000/static/js/bundle.js:212363:15)
at BrowserRouter (http://localhost:3000/static/js/bundle.js:210264:5)
at App
I tried it like a local package and as a published package. In case of local package I do proper linking in both ends (project + package)
There are another components in a package, which use hooks/states and they work! I don't know what's wrong here.
FYI: ActiveFilters is a component to show the active filters of datatable, which is iteracting with query param to sync them with a filters.