Как правильно соединить машинописный текст и реагирующий маршрутизатор при использовании render prop
и лямбда-функции для передачи состояния и передачи дочерним компонентам?
Я нахожусь на супер скалистой дороге, пытаясь подключить React Router к TypeScript.
Мне нужно передать реквизиты и состояние от моего родительского компонента его дочерним элементам.
предоставленный React Router. Для этого я использую render prop
как объяснено здесь
Исправить:
Lambdas are forbidden in JSX attributes due to their rendering performance impact
Я написал отдельный метод для исправления лямбда-ошибки и передал ее 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:
- Пытаясь обойти ошибки TypeScript и React Router, я добавил следующие типы в свой дочерний компонент:
// 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"
}
}