I have a react app that uses page navigation. The routing information is in App.js
const router = createBrowserRouter([
{
path: '/',
element: <RootLayout loggedInUser={loggedInUser} onShowModal={handleShowModal} config={config}/>,
children: [
{ path: '/', element: <HomePage config={config} loggedInUser={loggedInUser} userDataFeeds={userDataFeeds} initialActiveFeedName={initialActiveFeedName} /> },
{ path: '/manage', element: <ManagePage/>, children: [
{ path: '/manage/apps', element: <ManageApps appItems={availableAppItems} /> },
{ path: '/manage/feeds', element: <Outlet/>, children: [
{ index: true, element: <ManageFeeds userDataFeeds={userDataFeeds} onDeleteFeedSuccess={getUserDataFeeds} /> },
{ path: '/manage/feeds/add', element: <EditFeedForm loggedInUser={loggedInUser} action='Add' onEditFeedSuccess={handleEditFeedSuccess} /> },
{ path: '/manage/feeds/edit', element: <EditFeedForm loggedInUser={loggedInUser} action='Edit' onEditFeedSuccess={handleEditFeedSuccess} getAccessToken={getAccessToken} /> }
] }
] }
]
},
]);
Homepage.js is the component mapped to the root '/' route. In Homepage.js I have a hook that's triggered by any changes to a list of objects. The props.userDataFeeds in the snippet below is a list of objects.
useEffect(() => {
if (props.userDataFeeds && props.userDataFeeds.length){
console.log(props.initialActiveFeedName);
console.log(props.userDataFeeds);
if (props.initialActiveFeedName) {
const initialActiveFeed = props.userDataFeeds.find(x => x.userDataFeedName === props.initialActiveFeedName);
setActiveUserDataFeed(initialActiveFeed);
} else {
setActiveUserDataFeed(props.userDataFeeds[0]);
}
}
}, [props.userDataFeeds, props.initialActiveFeedName]);
The second dependency is there to further control the outcome of the hook.
The hook is triggered when a form in a separate page is submitted. After submission these things happen:
- form data is persisted to a DB
- the DB table is fetched again
- fetched data is used to update props.userDataFeeds
- finally the user is redirected (using navigate) to Homepage
The problem is that for some reason, this hook is always triggered twice by the props.userDataFeeds dependency even though it only gets changed once. I have confirmed it is only changed once by logging it every time this hook triggers.
In the first triggering, the state of props.userDataFeeds is identical to the state prior to the from submission.
In the second triggering, the state of props.userDataFeeds matched what was submitted in the form, which is what I expect.
I need to prevent the hook from triggering twice. Is this happening because Homepage.js is a child component of RootLayout? I'm baffled why the exact same state of props.userDataFeeds would trigger the hook when no changes to any of the objects in the array or their properties have taken place.
Update - I have already disabled strict mode. The problem persists.