我想对某些用户操作执行导航,比如按钮的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-dom
v5.x的withRouter
HOC一样。
解决方案
我不涉及将类组件转换为函数组件。下面是一个自定义withRouter
HOC:的示例
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");
};