Skip to content

Latest commit

 

History

History
228 lines (177 loc) · 5.37 KB

readme.md

File metadata and controls

228 lines (177 loc) · 5.37 KB

11 TableMock

Let's render a table and use a child component to render each row.

We will start by just creating some mock data.

We will take a startup point sample 03 State:

Summary steps:

  • Define a model entity (we will call it member).
  • Define a fake api (to take thing simple we will just make it synchronous).
  • We will row component, we will call it memberRow.
  • Create a table component, we will call it memberTable and make use of _memberRow.

Prerequisites

Install Node.js and npm (v6.6.0) if they are not already installed on your computer.

Verify that you are running at least node v6.x.x and npm 3.x.x by running node -v and npm -v in a terminal/console window. Older versions may produce errors.

Steps to build it

  • Copy the content from 03 State and execute npm install.
npm install
  • Let's define a model entity in src/model/member.ts:

./src/model/member.ts

export interface MemberEntity {
  id: number;
  login: string;
  avatar_url: string;
}

export const createEmptyMember = () : MemberEntity => ({
    id: -1,
    login: "",
    avatar_url: ""
});
  • Let's create some mock data in src/api/memberMockData.ts:

./src/api/memberMockData.ts

import {MemberEntity} from '../model/member';

const	MembersMockData : MemberEntity[] =
	[
		{
      id: 1457912,
      login: "brauliodiez",
      avatar_url: "https://avatars.githubusercontent.com/u/1457912?v=3"
		},
    {
      id: 4374977,
      login: "Nasdan",
      avatar_url: "https://avatars.githubusercontent.com/u/4374977?v=3"
    }
	];

export default MembersMockData;
  • Define a fake api (to take thing simple we will just make it synchronous) in src/api/memberAPI.ts:

src/api/memberAPI.ts

import {MemberEntity} from '../model/member';
import MembersMockData from './memberMockData';

// Sync mock data API, inspired from:
// https://gist.github.com/coryhouse/fd6232f95f9d601158e4
class MemberAPI {
  //This would be performed on the server in a real app. Just stubbing in.
  private _clone (item) {
  	return JSON.parse(JSON.stringify(item)); //return cloned copy so that the item is passed by value instead of by reference
  };

  // Just return a copy of the mock data
  getAllMembers() : Array<MemberEntity> {
		return this._clone(MembersMockData);
	}
}

export const memberAPI = new MemberAPI();
  • Now it's time jump into the interesting part, let's delete hello.tsx and nameEdit.tsx.

  • We are going to create an stateless component that will display a single row memberRow.tsx.

src/memberRow.tsx

import * as React from 'react';
import {MemberEntity} from './model/member';

export const MemberRow = (props: {member : MemberEntity}) =>
       <tr>
         <td>
           <img src={props.member.avatar_url} style ={{maxWidth: '10rem'}}/>
         </td>
         <td>
           <span>{props.member.id}</span>
         </td>
         <td>
           <span>{props.member.login}</span>
         </td>
       </tr>

We can't use max-widh in the param style in. We must write 'maxWidth' in the react components.

  • Then we are going to implement a component that will display a list of members (and will make use of rows), membersTable.tsx:

./src/membersTable.tsx

import * as React from 'react';
import {MemberEntity} from './model/member';
import {memberAPI} from './api/memberAPI';
import {MemberRow} from './memberRow';

interface Props {
}

// We define members as a state (the compoment holding this will be a container
// component)
interface State {
  members : MemberEntity[]
}

// Nice tsx guide: https://github.com/Microsoft/TypeScript/wiki/JSX
export class MembersTableComponent extends React.Component<Props, State> {

  constructor(props : Props){
        super(props);
        // set initial state
        this.state = {members: []};
  }

   // Standard react lifecycle function:
   // https://facebook.github.io/react/docs/component-specs.html
   public componentDidMount() {
     this.setState({members: memberAPI.getAllMembers()})
   }

   public render() {

       return (
        <div className="row">
          <h2> Members Page</h2>
          <table className="table">
            <thead>
              <tr>
                <th>
                  Avatar
                </th>
                <th>
                  Id
                </th>
                <th>
                  Name
                </th>
              </tr>
            </thead>
            <tbody>
              {
                this.state.members.map((member : MemberEntity) =>
                  <MemberRow key={member.id} member = {member}/>
                )
              }
            </tbody>
          </table>
        </div>
       );
  }
}
  • Let's update an app.tsx
import * as React from 'react';
- import { HelloComponent } from './hello';
- import { NameEditComponent } from './nameEdit';
+ import {MembersTableComponent} from './membersTable';

interface State {
  userName : string;
}

export class App extends React.Component<{}, State> {
  public render() {
      return (
       <>
+        <MembersTableComponent/>
-        <HelloComponent 
-         userName={this.state.userName} 
-        />
-        <NameEditComponent 
-         userName={this.state.userName} 
-         onChange={this.setUsernameState} 
-        />

       </>
      );
 }
}
  • Let's run the sample
npm start