【发布时间】:2019-09-09 15:20:27
【问题描述】:
构建一个 React 应用程序,我想让我的代码尽可能 DRY。我在这个项目中第一次开始使用 Typescript,我遇到了组件的可重用性问题,其中 JSX 在不同的情况下可以相同,但类型和接口会发生变化。
这是一个真实的例子:下面的代码是一个使用 TypeScript、Apollo / GraphQL 和 Redux 构建的 React 组件。它返回我数据库中所有足球队的表格,从后端 API 获取。
问题是,我想使用同一个组件来显示游戏表、玩家表等。
例如,我被我的Team 界面卡住了。每个团队只有一个id和一个name;但是每个游戏都有一个date、一个homeTeam和一个awayTeam, ascore`等等。
因此,我如何管理我的接口和我的类型,以便我可以重用这个组件?
import React from 'react';
import { connect } from 'react-redux';
import { setView, toggleDeleteElemModal } from '../../redux/actions';
import gql from 'graphql-tag';
import { Query } from 'react-apollo';
import { ApolloError } from 'apollo-client';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faInfo, faEdit, faTrash } from '@fortawesome/free-solid-svg-icons';
interface SectionTableProps {
setView: typeof setView
toggleDeleteElemModal : typeof toggleDeleteElemModal
}
interface Team {
id: string;
name: string;
}
interface Data {
allTeams?: Team[];
}
interface SectionTableQueryProps {
allTeams: Team[];
error?: ApolloError;
loading: boolean;
}
const GET_ALL_TEAMS = gql`
query {
allTeams {
id
name
}
}
`;
class SectionTableQuery extends Query<Data, {}> {}
const SectionTable = (props: SectionTableProps) => (
<table className="table table-hover table-responsive">
<thead>
<tr>
<th scope="col">ID</th>
<th scope="col">Name</th>
<th scope="col">Actions</th>
</tr>
</thead>
<SectionTableQuery query={GET_ALL_TEAMS}>
{({ data: { allTeams = [] } = {}, error, loading }) => {
if (loading) {
return <tbody><tr><td>LOADING</td></tr></tbody>
};
if (error !== undefined) {
return <tbody><tr><td>ERROR</td></tr></tbody>
};
return (
<tbody>
{allTeams.map((team: Team) => (
<tr key={team.id}>
<th scope="row">{team.id}</th>
<td>{team.name}</td>
<td className="d-flex justify-content-between">
<div onClick={() => props.setView("info")}>
<FontAwesomeIcon icon={faInfo} />
</div>
<div onClick={() => props.setView("edit")}>
<FontAwesomeIcon icon={faEdit} />
</div>
<div onClick={() => props.toggleDeleteElemModal()}>
<FontAwesomeIcon icon={faTrash} />
</div>
</td>
</tr>
))}
</tbody>
);
}}
</SectionTableQuery>
</table>
)
const mapDispatchToProps = { setView, toggleDeleteElemModal }
export default connect(null, mapDispatchToProps)(SectionTable);
【问题讨论】:
标签: reactjs typescript graphql apollo