I just finished a simple code test using React and I am not a React expert. I've just reviewed 2 hours of React document before this project. I have experience with other SPA frameworks.All in all, the key points:It is a 4-hour taskIt will be used in a big React projectI know my code has these defects:No testNo Redux to make it a strong stateless componentOther than that, what makes it a failed response to a code test?App.jsimport React, {Component} from 'react';import {Button, Form, FormGroup, Label, Input, FormFeedback} from 'reactstrap';import _ from 'lodash';import './App.css';import RepoList from ../RepoList/RepoList;class App extends Component {  constructor(props) {    super(props);    this.state = {      loading: false,      githubUsername: '',      githubUsernameState: '',      githubUsernameFeedback: '',      repos: []    };  }  render() {    return (        <div className=App>          <Form className=github-load-form>            <FormGroup color={this.state.githubUsernameState}>              <Label for=github-username>Github Username</Label>              <Input state={this.state.githubUsernameState}                     value={this.state.githubUsername}                     onChange={this.handleChange}                     type=text                     name=github-username                     id=github-username                     placeholder=github username/>              <FormFeedback>{this.state.githubUsernameFeedback}</FormFeedback>            </FormGroup>            <Button color=primary disabled={this.state.loading} onClick={this.loadGithubAccount}>              {this.state.loading &&              <i className=fa fa-spinner fa-spin fa-fw></i>              }              Load Repos            </Button>          </Form>          <RepoList repos={this.state.repos}/>        </div>    );  }  handleChange = (event) => {    this.setState({githubUsername: event.target.value});  }  loadGithubAccount = () => {    this.resetForm();    const validForm = this.validateForm();    if (!validForm)      return;    this.setLoadingState(true);    this.fetchRepoList(this.state.githubUsername);  }  fetchRepoList(repo) {    const getRepoListURL = `https://api.github.com/users/${repo}/repos`;    fetch(getRepoListURL)        .then(this.handleErrors)        .then(response => response.json())        .then(data => {          const repos = _.map(data, (repository) => {            return {              id: repository.id,              name: repository.name,              description: repository.description,              created_at: repository.created_at            };          });          this.setState((prevState) => {            return {repos: repos};          });          this.setLoadingState(false);        })        .catch(error => {          this.setLoadingState(false);          this.setFormGitHubUsernameResponse('danger', `Github Username ${error}`);        });  }  handleErrors(response) {    if (!response.ok) {      throw Error(response.statusText);    }    return response;  }  resetForm() {    this.setFormGitHubUsernameResponse('', '');    this.setLoadingState(false);    this.clearRepoList();  }  clearRepoList() {    this.setState((prevState) => {      return {repos: []};    });  }  setLoadingState(state = true) {    this.setState((prevState) => {      return {loading: state};    });  }  setFormGitHubUsernameResponse(state, feedback) {    this.setState((prevState) => {      return {        githubUsernameState: state,        githubUsernameFeedback: feedback      };    });  }  validateForm() {    const validUsername = /^[a-z\d](?:[a-z\d]|-(?=[a-z\d])){0,38}$/i.test(this.state.githubUsername);    if (!validUsername) {      this.setFormGitHubUsernameResponse('warning', 'Github Username invalid');    }    return validUsername;  }}export default App;RepoList.jsimport React, {Component} from 'react';import ReactTable from 'react-table';import Moment from 'react-moment';import _ from 'lodash';import './RepoList.css';class RepoList extends Component {  constructor(props) {    super(props);    this.state = {      repos: props.repos,      hiddenRows: 0,    };  }  componentWillReceiveProps(nextProps) {    // You don't have to do this check first, but it can help prevent an unneeded render    if (JSON.stringify(nextProps.repos) !== JSON.stringify(this.props.repos)) {      this.setState({        repos: nextProps.repos,        hiddenRows: 0      });    }  }  render() {    const columns = [{      Header: 'Id',      accessor: 'id'    }, {      Header: 'Name',      accessor: 'name',      Cell: props => <span title={props.value}>{props.value}</span>    }, {      Header: 'Description',      accessor: 'description',      Cell: props => <span title={props.value}>{props.value}</span>,      sortable: false    }, {      id: 'createdAt',      Header: 'Created at',      accessor: 'created_at',      sortable: false,      Cell: props => <Moment format=YYYY/MM/DD>{props.value}</Moment>    }, {      Header: '',      accessor: '',      sortable: false,      Cell: props =>          <div className=text-center>            <button type=button                    onClick={this.hideRow.bind(null, props.original.id)}                    className=btn btn-info>              Hide            </button>          </div>    }];    return (        <div className=repo-list>          <ReactTable              data={this.state.repos}              columns={columns}              className=-striped -highlight              defaultPageSize={10}              minRows={0}          />          <h2 className=text-center>Not showing {this.state.hiddenRows} repos</h2>        </div>    );  }  hideRow = (id) => {    const updatedRepos = _.filter(this.state.repos, function (repo) {      return repo.id !== id;    });    const updatedHiddenRows = this.state.hiddenRows + 1    this.setState({      repos: updatedRepos,      hiddenRows: updatedHiddenRows    });  }}export default RepoList;
An API based fetch page using React
javascript;react.js