如何在 React/Typescript 中定义历史记录和匹配类型(来自 React Router Dom)
how to define history and match type(from React Router Dom) in React/Typescript
我有一个使用 React、React Router Dom(RRD)、Redux 和 Typescript 的项目。 RRD 默认将 match
和 history
道具传递给我在 Route 组件道具中定义的子组件(见下文)。在我的组件内部,Redux 也向我的组件添加了两个道具,一个函数 (getPlaylist) 和一个对象 (auth)。
在我的组件中,当我输入所有道具时,我无法输入 match
和 history
。
我尝试了以下方法但没有成功:
- 添加了自定义道具的 RouteComponentProps
- 从 RRD 导入
History
,如下所示:从“react-router-dom”导入 { History } 并将其用作类型(参见我的代码)
我的组件
import React, { useEffect, useState, useMemo, useLayoutEffect } from "react"
import { connect } from "react-redux"
import PropTypes from "prop-types"
import CreatePlaylist from "../components/playlist/CreatePlaylist"
import { getPlaylist } from "../actions/playlistActions"
import isEmpty from "../utils/isEmpty"
import { Auth, Playlist } from "interfaces"
import { RouteComponentProps } from "react-router"
import { History } from "react-router-dom"
type EditPlaystProps2 = {
getPlaylist: Function
playlist: Playlist
auth: Auth
}
interface EditPlaystProps {
history: History
auth: Auth
getPlaylist: Function
playlist: Playlist
match: any
}
function EditPlaylist({
history,
auth,
getPlaylist,
playlist,
match,
}: RouteComponentProps<EditPlaystProps2>) {
const [currentPlaylist, setcurrentPlaylist] = useState({})
useEffect(() => {
const { isAuthenticated } = auth
if (!isAuthenticated) {
history.push("/login")
}
}, [auth, history])
useLayoutEffect(() => {
getPlaylist(match.params.slug)
}, [getPlaylist, match.params.slug])
useMemo(() => {
const { isAuthenticated } = auth
if (!isAuthenticated) {
history.push("/login")
}
if (playlist) {
setcurrentPlaylist(playlist)
}
}, [auth, history, setcurrentPlaylist, playlist])
const editQupplistContent = () => {
const playlistsHaveLoaded = !isEmpty(currentPlaylist.playlist)
if (playlistsHaveLoaded) {
return (
<CreatePlaylist
name={currentPlaylist.playlist.name}
slug={currentPlaylist.playlist.slug}
id={currentPlaylist.playlist._id}
title="Edit playlist"
buttonText="Edit playlist"
/>
)
}
}
return (
<div>
<h1>Edit playlist</h1>
{editQupplistContent()}
</div>
)
}
EditPlaylist.propTypes = {
getPlaylist: PropTypes.func.isRequired,
playlist: PropTypes.object,
auth: PropTypes.object.isRequired,
}
const mapStateToProps = (state) => ({
auth: state.auth,
playlist: state.playlist,
})
export default connect(mapStateToProps, { getPlaylist })(EditPlaylist)
type Props = RouteComponentProps & {
getPlaylist: Function,
playlist: Playlist,
auth: Auth,
}
像这样?
我有一个使用 React、React Router Dom(RRD)、Redux 和 Typescript 的项目。 RRD 默认将 match
和 history
道具传递给我在 Route 组件道具中定义的子组件(见下文)。在我的组件内部,Redux 也向我的组件添加了两个道具,一个函数 (getPlaylist) 和一个对象 (auth)。
在我的组件中,当我输入所有道具时,我无法输入 match
和 history
。
我尝试了以下方法但没有成功:
- 添加了自定义道具的 RouteComponentProps
- 从 RRD 导入
History
,如下所示:从“react-router-dom”导入 { History } 并将其用作类型(参见我的代码)
我的组件
import React, { useEffect, useState, useMemo, useLayoutEffect } from "react"
import { connect } from "react-redux"
import PropTypes from "prop-types"
import CreatePlaylist from "../components/playlist/CreatePlaylist"
import { getPlaylist } from "../actions/playlistActions"
import isEmpty from "../utils/isEmpty"
import { Auth, Playlist } from "interfaces"
import { RouteComponentProps } from "react-router"
import { History } from "react-router-dom"
type EditPlaystProps2 = {
getPlaylist: Function
playlist: Playlist
auth: Auth
}
interface EditPlaystProps {
history: History
auth: Auth
getPlaylist: Function
playlist: Playlist
match: any
}
function EditPlaylist({
history,
auth,
getPlaylist,
playlist,
match,
}: RouteComponentProps<EditPlaystProps2>) {
const [currentPlaylist, setcurrentPlaylist] = useState({})
useEffect(() => {
const { isAuthenticated } = auth
if (!isAuthenticated) {
history.push("/login")
}
}, [auth, history])
useLayoutEffect(() => {
getPlaylist(match.params.slug)
}, [getPlaylist, match.params.slug])
useMemo(() => {
const { isAuthenticated } = auth
if (!isAuthenticated) {
history.push("/login")
}
if (playlist) {
setcurrentPlaylist(playlist)
}
}, [auth, history, setcurrentPlaylist, playlist])
const editQupplistContent = () => {
const playlistsHaveLoaded = !isEmpty(currentPlaylist.playlist)
if (playlistsHaveLoaded) {
return (
<CreatePlaylist
name={currentPlaylist.playlist.name}
slug={currentPlaylist.playlist.slug}
id={currentPlaylist.playlist._id}
title="Edit playlist"
buttonText="Edit playlist"
/>
)
}
}
return (
<div>
<h1>Edit playlist</h1>
{editQupplistContent()}
</div>
)
}
EditPlaylist.propTypes = {
getPlaylist: PropTypes.func.isRequired,
playlist: PropTypes.object,
auth: PropTypes.object.isRequired,
}
const mapStateToProps = (state) => ({
auth: state.auth,
playlist: state.playlist,
})
export default connect(mapStateToProps, { getPlaylist })(EditPlaylist)
type Props = RouteComponentProps & {
getPlaylist: Function,
playlist: Playlist,
auth: Auth,
}
像这样?