以编程方式重定向到react路由器v6中的路由时出现问题



我想对某些用户操作执行导航,比如按钮的onSubmit。假设用户点击Add contact按钮I want react router重定向到"/"这是主页。目前我正面临这个问题-->TypeError:无法读取未定义的属性(读取"push"(。作为一个初学者,我非常感谢专家的帮助。

AddContacts.js

import React, { Component } from "react";
import { Consumer } from "../../context";
import TextInputGroup from "../layout/TextInputGroup";
import { v4 as uuidv4 } from "uuid";
import { useNavigate } from "react-router-dom";
class AddContacts extends Component {
state = {
name: "",
email: "",
phone: "",
errors: {},
};
onSubmit = (dispatch, e) => {
e.preventDefault();
const { name, email, phone } = this.state;
//Check for errors
if (name === "") {
this.setState({ errors: { name: "Name is required" } });
return;
}
if (email === "") {
this.setState({ errors: { email: "Email is required" } });
return;
}
if (phone === "") {
this.setState({ errors: { phone: "Phone is required" } });
return;
}
const newContact = {
id: uuidv4(),
name,
email,
phone,
};
dispatch({ type: "ADD_CONTACT", payload: newContact });
this.setState({
name: "",
email: "",
phone: "",
errors: {},
});
this.props.navigate.push("/");
};
onChange = (e) => this.setState({ [e.target.name]: e.target.value });
render() {
const { name, email, phone, errors } = this.state;
return (
<Consumer>
{(value) => {
const { dispatch } = value;
return (
<div className="card mb-3">
<div className="card-header">Add Contacts</div>
<div className="card-body">
<form onSubmit={this.onSubmit.bind(this, dispatch)}>
<TextInputGroup
label="Name"
name="name"
placeholder="Enter Name..."
value={name}
onChange={this.onChange}
error={errors.name}
/>
<TextInputGroup
label="Email"
name="email"
type="email"
placeholder="Enter Email..."
value={email}
onChange={this.onChange}
error={errors.email}
/>
<TextInputGroup
label="Phone"
name="phone"
placeholder="Enter Phone..."
value={phone}
onChange={this.onChange}
error={errors.phone}
/>
<input
type="submit"
value="Add Contact"
className="btn btn-light btn-block mt-3"
/>
</form>
</div>
</div>
);
}}
</Consumer>
);
}
}
export default AddContacts;

这是App.js文件

import React, { Component } from "react";
import { BrowserRouter, Routes, Route, Link } from "react-router-dom";
import Contacts from "./components/contacts/Contacts";
import Header from "./components/layout/Header";
import AddContacts from "./components/contacts/AddContacts";
import About from "./components/pages/About";
import { Provider } from "./context";
import "bootstrap/dist/css/bootstrap.min.css";
import "./App.css";
function App() {
return (
<Provider>
<BrowserRouter>
<div className="App">
<Header branding="Contact manager" />
<div className="container">
<Routes>
<Route path="/" element={<Contacts />} />{" "}
<Route path="/contact/add/*" element={<AddContacts />} />{" "}
<Route path="about/*" element={<About />} />{" "}
</Routes>{" "}
</div>{" "}
</div>{" "}
</BrowserRouter>{" "}
</Provider>
);
}
export default App;

问题

TypeError: Cannot read properties of undefined (reading 'push')

这是由于您试图从不存在的navigate道具进行导航,该道具未定义。

this.props.navigate.push("/");

useNavigate钩子只与函数组件兼容,因此如果您希望/需要将navigate与类组件一起使用,则必须将AddContacts转换为函数组件,或者滚动您自己的自定义withRouter高阶组件以注入";路线道具";与react-router-domv5.x的withRouterHOC一样。

解决方案

我不涉及将类组件转换为函数组件。下面是一个自定义withRouterHOC:的示例

const withRouter = WrappedComponent => props => {
const navigate = useNavigate();
// etc... other react-router-dom v6 hooks
return (
<WrappedComponent
{...props}
navigate={navigate}
// etc...
/>
);
};

并用新的HOC装饰AddContacts组件。

export default withRouter(AddContacts);

这将把一个navigate道具(和您设置的任何其他道具(传递给装饰的组件,this.navigate现在将被定义。

此外,导航API从v5更改为v6,它不再是正在使用的直接history对象。navigate是一个函数而不是一个对象。要使用该函数并传递1或2个参数,第一个是目标路径,第二个是可选的";选项";具有CCD_ 14和/或CCD_。

interface NavigateFunction {
(
to: To,
options?: { replace?: boolean; state?: State }
): void;
(delta: number): void;
}

现在按如下方式导航:

this.props.navigate("/");

如何在React Router v6中重定向

import {  useNavigate  } from "react-router-dom";
const navigate = useNavigate();

const handleClick = () => {
navigate("/dashboard");
};

最新更新