react-router 和打字稿 "match" 问题 Link 到路由
react-router and typescript "match" issue in Link to routing
由于我是 React 和 TypeScript 的新手,我已经阅读了几篇关于如何使用 TypeScript 从 react-router 中获取 "match" 属性 的文章,但我还没有能够成功地做到这一点。我没有要传递的参数,我只想能够使用 react-router 的 match.url。
所以我看到的例子是 login.tsx 文件中的字段应该使用 {match.url}。我在这里尝试了 React 4 路由器演示:https://codesandbox.io/s/nn8x24vm60?from-embed 他们使用 {${match.url}/register
} 的地方,但这也不起作用。然后我看到一些帖子,人们说你必须声明一个接口,但它在 RouteComponent 和 Route 之间分开,而且大多数都在处理参数。基本上我想要它做的就是当我单击 link 切换到注册路由时(它在 register.tsx 中 - 此处未显示,因为它是一个简单的文件,上面只有 header ).
目前它抛出以下错误:
"Error TS2739 (TS) Type '{}' is missing the following properties from type
'Readonly<MyProps & RouteComponentProps<{}, StaticContext, any>>': register, history, location, match"
任何关于我做错了什么的帮助将不胜感激。
app.tsx 文件:
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter as Router, Redirect, Link, Route, Switch } from 'react-router-dom';
import { Home } from './home';
import { Register } from './register';
import { NavBar } from './navbar';
export class App extends React.Component<{}, {}> {
render() {
return (
<Router>
<div>
<NavBar/>
<Switch>
<Route path="/" component={Home} />
<Route path="/register" component={Register} />
</Switch>
</div>
</Router>
);
}
}
ReactDOM.render(, document.getElementById('root'));
home.tsx 文件:
import React from 'react';
import { Login } from './login';
import { Jumbotron } from 'react-bootstrap';
const jumboStyle = {
background: 'lightgray',
height: '20%',
width: '40%',
margin: 'auto'
};
export class Home extends React.Component<{}, {}> {
render() {
return (
<div>
< Jumbotron style={jumboStyle}>
<h1>Welcome to the new League!</h1>
<h4>Please log in with your username and password to continue</h4>
<Login />
<br />
<br />
</Jumbotron>
</div>
);
}
}
login.tsx 文件:
import React from 'react';
import { Link, RouteComponentProps } from "react-router-dom";
import TextField from '@material-ui/core/TextField';
import Button from '@material-ui/core/Button';
import { Alert } from 'react-bootstrap';
import { Register } from './register';
interface IState {
[key: string]: any; // or the type of your input
}
interface MyProps {
register: Register
}
const styles = {
background: 'lightblue'
};
export class Login extends React.Component<MyProps & RouteComponentProps, IState> {
constructor(props) {
super(props);
this.state = {
username: '',
password: '',
authorized: false
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
const target = event.target;
const value = target.value;
const name = target.name;
this.setState({
[name]:value
});
}
handleSubmit(event) {
//we are goingto submit the form to the database
event.prevent.default();
}
render() {
return (
<div>
<form noValidate autoComplete="off" onSubmit={this.handleSubmit} style={{ textAlign: 'center' }}>
<TextField
id="username"
name="username"
label="UserName"
helperText="Enter your Username"
value={this.state.username}
onChange={this.handleChange}
required={true}
style={styles}
/>
<br />
<TextField
id="password"
name="password"
type="password"
helperText="Enter your password"
label="Password"
onChange={this.handleChange}
required={true}
style={styles}
/>
<br />
<br />
<br/>
<Button
type="submit"
value="Submit"
variant="contained"
color="primary"
>Submit</Button>
<br />
<br/>
<Alert variant="info">
<Alert.Heading>Don't Have An Account Setup?</Alert.Heading>
<div>
<Link to={`${this.props.match.url}/register`}>Register Here</Link>
</div>
</Alert>
</form>
</div>
)
}
}
您需要将 props 从 Home 组件传递到 Login 组件。
<Login match={this.props.match}/>
应该可以。
默认情况下,react-router
属性(例如 match
)只会自动注入路由渲染的组件(本例中为 Home
)。您可以使用 withRouter
包装器将它们添加到您的组件中。然后您必须使用包装组件而不是内部组件。
import {withRouter} from 'react-router';
...
class LoginInternal extends React.Component<MyProps & RouteComponentProps, IState> {
...
export const Login = withRouter(LoginInternal);
由于我是 React 和 TypeScript 的新手,我已经阅读了几篇关于如何使用 TypeScript 从 react-router 中获取 "match" 属性 的文章,但我还没有能够成功地做到这一点。我没有要传递的参数,我只想能够使用 react-router 的 match.url。
所以我看到的例子是 login.tsx 文件中的字段应该使用 {match.url}。我在这里尝试了 React 4 路由器演示:https://codesandbox.io/s/nn8x24vm60?from-embed 他们使用 {${match.url}/register
} 的地方,但这也不起作用。然后我看到一些帖子,人们说你必须声明一个接口,但它在 RouteComponent 和 Route 之间分开,而且大多数都在处理参数。基本上我想要它做的就是当我单击 link 切换到注册路由时(它在 register.tsx 中 - 此处未显示,因为它是一个简单的文件,上面只有 header ).
目前它抛出以下错误:
"Error TS2739 (TS) Type '{}' is missing the following properties from type
'Readonly<MyProps & RouteComponentProps<{}, StaticContext, any>>': register, history, location, match"
任何关于我做错了什么的帮助将不胜感激。
app.tsx 文件:
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter as Router, Redirect, Link, Route, Switch } from 'react-router-dom';
import { Home } from './home';
import { Register } from './register';
import { NavBar } from './navbar';
export class App extends React.Component<{}, {}> {
render() {
return (
<Router>
<div>
<NavBar/>
<Switch>
<Route path="/" component={Home} />
<Route path="/register" component={Register} />
</Switch>
</div>
</Router>
);
}
}
ReactDOM.render(, document.getElementById('root'));
home.tsx 文件:
import React from 'react';
import { Login } from './login';
import { Jumbotron } from 'react-bootstrap';
const jumboStyle = {
background: 'lightgray',
height: '20%',
width: '40%',
margin: 'auto'
};
export class Home extends React.Component<{}, {}> {
render() {
return (
<div>
< Jumbotron style={jumboStyle}>
<h1>Welcome to the new League!</h1>
<h4>Please log in with your username and password to continue</h4>
<Login />
<br />
<br />
</Jumbotron>
</div>
);
}
}
login.tsx 文件:
import React from 'react';
import { Link, RouteComponentProps } from "react-router-dom";
import TextField from '@material-ui/core/TextField';
import Button from '@material-ui/core/Button';
import { Alert } from 'react-bootstrap';
import { Register } from './register';
interface IState {
[key: string]: any; // or the type of your input
}
interface MyProps {
register: Register
}
const styles = {
background: 'lightblue'
};
export class Login extends React.Component<MyProps & RouteComponentProps, IState> {
constructor(props) {
super(props);
this.state = {
username: '',
password: '',
authorized: false
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
const target = event.target;
const value = target.value;
const name = target.name;
this.setState({
[name]:value
});
}
handleSubmit(event) {
//we are goingto submit the form to the database
event.prevent.default();
}
render() {
return (
<div>
<form noValidate autoComplete="off" onSubmit={this.handleSubmit} style={{ textAlign: 'center' }}>
<TextField
id="username"
name="username"
label="UserName"
helperText="Enter your Username"
value={this.state.username}
onChange={this.handleChange}
required={true}
style={styles}
/>
<br />
<TextField
id="password"
name="password"
type="password"
helperText="Enter your password"
label="Password"
onChange={this.handleChange}
required={true}
style={styles}
/>
<br />
<br />
<br/>
<Button
type="submit"
value="Submit"
variant="contained"
color="primary"
>Submit</Button>
<br />
<br/>
<Alert variant="info">
<Alert.Heading>Don't Have An Account Setup?</Alert.Heading>
<div>
<Link to={`${this.props.match.url}/register`}>Register Here</Link>
</div>
</Alert>
</form>
</div>
)
}
}
您需要将 props 从 Home 组件传递到 Login 组件。
<Login match={this.props.match}/>
应该可以。
默认情况下,react-router
属性(例如 match
)只会自动注入路由渲染的组件(本例中为 Home
)。您可以使用 withRouter
包装器将它们添加到您的组件中。然后您必须使用包装组件而不是内部组件。
import {withRouter} from 'react-router';
...
class LoginInternal extends React.Component<MyProps & RouteComponentProps, IState> {
...
export const Login = withRouter(LoginInternal);