I'm making wizard form in react and have got a problem with routing page routing is like this
home -> wizard form(step1) -> step2 ->step3..
<Route
path="/startAProgram/step1"
exact
render={() => <StartAProgram />}
/>
//app.js
//There are many routes in app.js and one of routes is StartAProgram(wizard form)
function StartAProgram() {
return (
<WrapperDiv>
<Stepper />
<ProgramName /> {/* this is step 1 */}
<Router>
{/* <Route path="startAProgram/step1" render={() => <ProgramName />} /> */}
<Switch>
<Route
path="startAProgram/step2"
exact
render={() => <SetTargets />}
/>
<Route
path="startAProgram/step3"
render={() => <ParticipationGuidelines />}
/>
</Switch>
</Router>
</WrapperDiv>
);
}
function ProgramName() {
const programName = useSelector((state) => state.programName);
const {
register,
handleSubmit,
formState: { errors },
} = useForm({
defaultValues: programName,
});
const dispatch = useDispatch();
const history = useHistory();
const handleOnSubmit = (data) => {
sessionStorage.setItem('programName', Object.values(data));
dispatch(submitStep1(data));
history.push('./step2');
console.log('next~');
};
return (
<form onSubmit={handleSubmit(handleOnSubmit)}>
<Text size={30} weight={800} mb={10}>
Step 1. Program name
</Text>
<label htmlFor="programName">
Program Name
<input
name="programName"
{...register('programName', { required: 'fill out!' })}
/>
<ErrorMessage errors={errors} name="programName" as="p" />
</label>
<Button type="submit">next</Button>
</form>
);
}
It would be Step2 if the form validation is successful but Step2 component rendering is not working currently. Page Step 1 is rendering well, but it is not letting me render step 2 and more. Anyone can solve this problem?
StartAProgram
is rendering these other routes, so when you navigate to one of those routes, the route rendering StartAProgram
is no longer matched and those other routes you are linking to are no longer mounted.
Make the root stepper route path more generic so it can match rendering any of the steps.
<Route path="/startAProgram" component={StartAProgram} />
Then refactor StartAProgram
to render ProgramName
back on a ".../step1"
path. Remove the extra Router
component, you only need one router per app.
function StartAProgram() {
return (
<WrapperDiv>
<Stepper />
<Switch>
<Route path="/startAProgram/step1" component={ProgramName} />
<Route path="/startAProgram/step2" component={SetTargets} />
<Route
path="/startAProgram/step3"
component={ParticipationGuidelines}
/>
</Switch>
</WrapperDiv>
);
}
When nesting descendent routes it is a common pattern to use the useRouteMatch
hook to dynamically build relative paths.
import { Switch, Route, useRouteMatch } from 'react-router-dom';
function StartAProgram() {
const { path } = useRouteMatch();
return (
<WrapperDiv>
<Stepper />
<Switch>
<Route path={`${path}/step1`} component={ProgramName} />
<Route path={`${path}/step2`} component={SetTargets} />
<Route path={`${path}/step3`} component={ParticipationGuidelines} />
</Switch>
</WrapperDiv>
);
}
This is helpful/useful if you need to move the StartAProgram
component around onto a different path, the links and routes from here work relative to the current location.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.