If you would like to use a class, then you will need to wrap it with the withRouter
. I provide an example below:
This is my class for the movie form:
class MovieForm extends Form {
state = {
data: {
title: "",
genreId: "",
numberInStock: "",
dailyRentalRate: ""
},
genres: [],
errors: {}
};
schema = {
_id: Joi.string(),
title: Joi.string()
.required()
.label("Title"),
genreId: Joi.string()
.required()
.label("Genre"),
numberInStock: Joi.number()
.required()
.min(0)
.max(100)
.label("Number in Stock"),
dailyRentalRate: Joi.number()
.required()
.min(0)
.max(10)
.label("Daily Rental Rate")
};
componentDidMount() {
const genres = getGenres();
this.setState({ genres });
// const movieId = this.props.match.params.id;
const movieId = this.props.params.id;
if (movieId === "new") return;
const movie = getMovie(movieId);
if (!movie) return this.props.history.replace("/not-found");
this.setState({ data: this.mapToViewModel(movie) });
}
mapToViewModel(movie) {
return {
_id: movie._id,
title: movie.title,
genreId: movie.genre._id,
numberInStock: movie.numberInStock,
dailyRentalRate: movie.dailyRentalRate
};
}
doSubmit = () => {
saveMovie(this.state.data);
this.props.navigate("/movies");
};
render() {
return (
<div>
<h1>Movie Form</h1>
<form onSubmit={this.handleSubmit}>
{this.renderInput("title", "Title")}
{this.renderSelect("genreId", "Genre", this.state.genres)}
{this.renderInput("numberInStock", "Number in Stock", "number")}
{this.renderInput("dailyRentalRate", "Rate")}
{this.renderButton("Save")}
</form>
</div>
);
}
}
I write a wrapper outside of the class:
const withRouter = WrappedComponent => props => {
const params = useParams();
const navigate = useNavigate();
return (
<WrappedComponent
{...props}
params={params}
navigate={navigate}
/>
);
};
Now, at the end of the file I will export it like below:
export default withRouter(MovieForm);
Insdie the withRouter
, I get all the functions that I will use later inside the class:
const params = useParams();
const navigate = useNavigate();