以编程方式重定向到反应路由器 v6 中的路由的问题
我想对某些用户操作执行导航,例如按钮的 onSubmit.假设用户单击添加联系人按钮,我希望 react-router 在/"中重定向这是主页.目前我正面临这个问题-->TypeError:无法读取未定义的属性(读取推送").作为初学者,我非常感谢专家的帮助.
AddContacts.js
import React, { Component } from "react";从../../context"导入{消费者};从../layout/TextInputGroup"导入 TextInputGroup;从uuid"导入 { v4 as uuidv4 };从react-router-dom"导入 { useNavigate };类 AddContacts 扩展组件 {状态 = {名称:",电子邮件:",电话:",错误:{},};onSubmit = (dispatch, e) =>{e.preventDefault();const { 姓名、电子邮件、电话 } = this.state;//检查错误if (name === "") {this.setState({ errors: { name: "Name is required" } });返回;}如果(电子邮件==="){this.setState({ errors: { email: "Email is required" } });返回;}如果(电话==="){this.setState({ errors: { phone: "Phone is required" } });返回;}常量新联系人 = {id: uuidv4(),名称,电子邮件,电话,};dispatch({ type: "ADD_CONTACT", payload: newContact });这个.setState({名称:",电子邮件:",电话:",错误:{},});this.props.navigate.push("/");};onChange = (e) =>this.setState({ [e.target.name]: e.target.value });使成为() {const { 姓名、电子邮件、电话、错误 } = this.state;返回 (<消费者>{(值) =>{常量 { 调度 } = 值;返回 (<div className="card mb-3"><div className="card-header">添加联系人</div><div className=""card-body"><form onSubmit={this.onSubmit.bind(this, dispatch)}><文本输入组标签=名称"名称=名称";placeholder=输入名称..."值={名称}onChange={this.onChange}错误={errors.name}/><文本输入组标签=电子邮件"名称=电子邮件";类型=电子邮件";placeholder=输入电子邮件..."价值={电子邮件}onChange={this.onChange}错误={errors.email}/><文本输入组标签=电话"名称=电话";placeholder=输入电话..."价值={电话}onChange={this.onChange}错误={errors.phone}/><输入类型=提交";value="添加联系人"className="btn btn-light btn-block mt-3"/></表格></div></div>);}}</消费者>);}}导出默认的 AddContacts;
这是 App.js 文件
import React, { Component } from "react";从react-router-dom"导入 { BrowserRouter, Routes, Route, Link };从./components/contacts/Contacts"导入联系人;从./components/layout/Header"导入标题;从./components/contacts/AddContacts"导入 AddContacts;从./components/pages/About"导入关于;从./context"导入{ Provider };导入bootstrap/dist/css/bootstrap.min.css";导入./App.css";函数应用程序(){返回 (<提供者><浏览器路由器><div className="App"><标题品牌=联系人经理"/><div className=容器"><路线><路由路径="/";element={<联系人/>}/>{""}<路由路径="/contact/add/*"element={<AddContacts/>}/>{""}<路线路径=约/*"元素={<关于/>}/>{""}</路线>{""}</div>{>"}</div>{>"}</BrowserRouter>{""}</提供者>);}导出默认应用程序;
解决方案 问题
<块引用>TypeError:无法读取未定义的属性(读取推送")
这是因为您尝试从不存在的 navigate
道具导航,它是未定义的.
this.props.navigate.push("/");
useNavigate
钩子仅与功能组件兼容,因此您希望/需要将 navigate
与类组件一起使用,您必须转换 AddContacts
到函数组件,或滚动您自己的自定义 withRouter
高阶组件以注入路由道具";就像 react-router-dom
v5.x 中的 withRouter
HOC 一样.
解决方案
我不会介绍将类组件转换为函数组件.这是一个示例自定义 withRouter
HOC:
const withRouter = WrappedComponent =>道具=>{常量导航 = useNavigate();//等等...其他 react-router-dom v6 钩子返回 (<包裹组件{...道具}导航={导航}//等等.../>);};
并用新的 HOC 装饰 AddContacts
组件.
export default withRouter(AddContacts);
现在这会将 navigate
道具(和您设置的任何其他道具)传递给装饰组件,并且 this.navigate
现在将是已定义.
此外,导航 API 从 v5 更改为 v6,不再使用直接的 history
对象.navigate
是一个函数而不是一个对象.要使用您调用函数并传递 1 或 2 个参数,第一个是目标路径,第二个是可选的选项";带有 replace
和/或 state
键/值的对象.
接口 NavigateFunction {(到:到,选项?:{替换?:布尔值;状态?:状态 }): 空白;(增量:数字):无效;}
现在如下导航:
this.props.navigate("/");
I want to perform navigation on certain user actions, say onSubmit of a button. suppose a user clicks on the Add contact button I want react-router to redirect in "/" which is the home page. At the moment I am facing this problem--> TypeError: Cannot read properties of undefined (reading 'push'). As a beginner, I would really appreciate experts' help.
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;
Here is the App.js file
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;
解决方案
Issue
TypeError: Cannot read properties of undefined (reading 'push')
This is cause by you attempting to navigate from a navigate
prop that doesn't exist, it's undefined.
this.props.navigate.push("/");
The useNavigate
hook is only compatible with function components, so of you want/need to use navigate
with a class component you must either convert AddContacts
to a function component, or roll your own custom withRouter
Higher Order Component to inject the "route props" like the withRouter
HOC from react-router-dom
v5.x did.
Solution
I won't cover converting a class component to function component. Here's an example custom withRouter
HOC:
const withRouter = WrappedComponent => props => {
const navigate = useNavigate();
// etc... other react-router-dom v6 hooks
return (
<WrappedComponent
{...props}
navigate={navigate}
// etc...
/>
);
};
And decorate the AddContacts
component with the new HOC.
export default withRouter(AddContacts);
This will now pass a navigate
prop (and any others you set up) to the decorated components and this.navigate
will now be defined.
Additionally, the navigation API changed from v5 to v6, it's no longer the direct history
object being used. navigate
is a function instead of an object. To use you invoke the function and pass 1 or 2 arguments, the first is the target path, the second is an optional "options" object with replace
and/or state
key/values.
interface NavigateFunction { ( to: To, options?: { replace?: boolean; state?: State } ): void; (delta: number): void; }
To navigate now as follows:
this.props.navigate("/");
相关文章