I have a problem with navigation between two routes of same component.
I have a page where there is a form to create and edit user. The routes are:
/user
/user/:id
But when try navigate from /user/:id to /user to create new user, the states of component not redeclared. The states come with the same value of page /user/:id. This is occur only when navigate to same component.
See routes:
<Route path='user/:id' element={<UserForm />} />
<Route path='user' element={<UserForm />} />
The component:
const UserForm = () => {
const navigate = useNavigate();
const params = useParams<FormParams>();
// const [searchParams, setSearchParams] = useSearchParams();
const [loading, setLoading] = useState<boolean>(true);
const [message, setMessage] = useState<MessageProps>();
const [data, setData] = useState<UserModel>(newData);
...
}
export default UserForm;
Redirect Function:
const newForm = () => {
try {
debugger;
navigate('/user');
} catch (error) {
console.log("ERROR");
}
}
If I refresh page, the states is redeclared. As it should happen in the redirect.
CodePudding user response:
react-router-dom is optimized to not unnecessarily unmount and remount components.
<Route path='user/:id' element={<UserForm />} />
<Route path='user' element={<UserForm />} />
When switching between "/user" and "/user/:id" the UserForm component will only get rerendered. The same is true if you navigate from one "/user/:id" path to a different "/user/:id" path. It's clear that UserForm has a dependency on this id route path parameter. You've a couple options for handling this.
Use a
useEffecthook with a dependency on theidroute param and rerun/reset any state.const UserForm = () => { const navigate = useNavigate(); const { id } = useParams<FormParams>(); // const [searchParams, setSearchParams] = useSearchParams(); const [loading, setLoading] = useState<boolean>(true); const [message, setMessage] = useState<MessageProps>(); const [data, setData] = useState<UserModel>(newData); useEffect(() => { // reset state or re-issue side-effect based on id param }, [id]); ... }Add a React key to the
UserFormcomponent in the route so React will unmount/mount a new instance when switching between"/user"and"/user/:id". Note however that you'd still need auseEffecthook to rerun/reset logic/state when staying on the same route and only theidchanges.<Route path='user/:id' element={<UserForm key="root" />} /> <Route path='user' element={<UserForm key="id" />} />
