Uj Corb
Uj Corb

Reputation: 2189

make apollo query component reusable in React

So I am creating a table component in my React Project with which I display a list of thing like Teams, Games, Players, etc.

I want to have one single component for this table and be able to re-use it as many times as I want to display different kinds of data.

The thing is I use Apollo & GraphQL to fetch that data from my DB and each query has a different data name: e.g. if I fetch all my teams i'll have data.allTeams but if I fetch all my games I'll have data.allGames:

class SectionTable extends React.Component<SectionTableProps, {}> {
  constructor(props: SectionTableProps) {
    super(props);
  }
  render() {
    return (
          <SectionTableQuery query={this.props.query} >
          {({ 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((elem) => (
                    <tr key={elem.id}>
                      <th scope="row">{elem.id}</th>
                      {Object.keys(elem).map((k, i) => {
                        if (k !== "id" && k !== "__typename") {
                          return (<td key={elem[k]}>{elem[k]}</td>)
                        }
                      })}
                    </tr>
                ))}
              </tbody>
            );
          }}
        </SectionTableQuery>
    )
  }
} 

I one case I'll want to map through allTeams but in the other case I'll want to map through allGames.

How can I change my code so that It can take the data name as an argument ?

Upvotes: 0

Views: 304

Answers (1)

duc mai
duc mai

Reputation: 1422

maybe simple sending a props to point out what is the list to loop

class SectionTable extends React.Component<SectionTableProps, {}> {
  ...
  render() {
    const { listName, query } = this.props;
    return (
      <SectionTableQuery query={query}>
        {({ data = {}, error, loading }) => {
          if (loading) {
            ...
          }
          if (error !== undefined) {
            ...
          }
          return (
            <tbody>
              {(data[listName]||[]).map(elem => (
                <tr key={elem.id}>
                  <th scope="row">{elem.id}</th>
                  {Object.keys(elem).map((k, i) => {
                    if (k !== 'id' && k !== '__typename') {
                      return <td key={elem[k]}>{elem[k]}</td>;
                    }
                  })}
                </tr>
              ))}
            </tbody>
          );
        }}
      </SectionTableQuery>
    );
  }
}
<SectionTable query={...} listName="allTeams" />
<SectionTable query={...} listName="allGames" />

if you want to have different row then adding even a render function for customizing the row

Upvotes: 1

Related Questions