使用render prop
和lambda函数将状态和道具传递给子组件时,将打字稿和react-router连接在一起的正确方法是什么?
我在尝试将React Router连接到TypeScript的路上非常艰难。
我需要将道具和状态从我的父组件传递给子组件 由React Router渲染。为此,我正在按照here
的说明使用render prop
要解决:
Lambdas are forbidden in JSX attributes due to their rendering performance impact
我写了一个单独的方法来解决Lambda错误,并将其传递给render
中的Route
,即:
public gameRoute = (props: any, state: object) => {
return <Game {...props} {...this.state} />
}
public render(): JSX.Element {
const { person, loading, error } = this.state
return (
<BrowserRouter>
<div className="App">
<ul>
<li>
<Link to="/">home</Link>
</li>
<li>
<Link to="/play-game">Play Game!</Link>
</li>
</ul>
<Switch>
<Route path="/play-game" render={this.gameRoute} />
</Switch>
</div>
</BrowserRouter>
)
}
主要问题是TypeScript错误:
// Child Component
import React from 'react'
import { RouteComponentProps } from 'react-router-dom'
interface GameProps extends RouteComponentProps<any>, React.Props<any> {
person: object[] | any
loading: boolean | string
error: null
}
export const Game: React.SFC<GameProps> = ({ person }) => (
<p className="error">Game is ON! {person}</p>
)
// Parent Compoment
import React, { Component } from 'react'
import { StaticContext } from 'react-router'
import { BrowserRouter, Link, Route, RouteComponentProps, Switch } from 'react-router-dom'
import './App.css'
import { Error } from './Error/Error'
import { Game } from './Game/Game'
import { Loading } from './Loading/Loading'
interface AppProps extends RouteComponentProps<any> { }
interface AppState {
person: object[]
loading: boolean | string
error: null
}
export default class App extends Component<AppProps, AppState> {
public state = {
error: null,
loading: true,
person: [],
}
public async componentDidMount() {
const url = 'myApi'
try {
const res = await fetch(url)
const data = await res.json()
this.setState({ person: data, loading: false })
} catch (error) {
this.setState({ error, loading: false })
console.error(error)
}
}
public gameRoute = (props: any, state: object) => {
return <Game {...props} {...this.state} />
}
public render(): JSX.Element {
const { person, loading, error } = this.state
return (
<BrowserRouter>
<div className="App">
<ul>
<li>
<Link to="/">home</Link>
</li>
<li>
<Link to="/play-game">Play Game!</Link>
</li>
</ul>
<Switch>
<Route path="/play-game" render={this.gameRoute} />
</Switch>
</div>
</BrowserRouter>
)
}
}
我在黑暗中飞翔,所以您的指导将不胜感激
这是我的package.json,以防万一:
{
"name": "my-app",
"version": "0.1.0",
"private": true,
"dependencies": {
"@types/jest": "^23.3.12",
"@types/node": "^10.12.18",
"@types/react": "^16.7.18",
"@types/react-dom": "^16.0.11",
"@types/react-router": "^4.4.3",
"@types/react-router-dom": "^4.3.1",
"react": "^16.7.0",
"react-dom": "^16.7.0",
"react-router-dom": "^4.3.1",
"react-scripts": "2.1.3",
"typescript": "^3.2.2"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject",
"tslint-check": "tslint-config-prettier-check ./tslint.json",
"lint": "tslint -c tslint.json src/**/*.{ts,tsx} --fix --format verbose"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": [
">0.2%",
"not dead",
"not ie <= 11",
"not op_mini all"
],
"devDependencies": {
"tslint": "^5.12.1",
"tslint-config-prettier": "^1.17.0",
"tslint-plugin-prettier": "^2.0.1",
"tslint-react": "^3.6.0"
}
}