Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I am working on a React-Redux app, which is a CRUD application for a school. The first part was to implement adding/removal of classes (aliased to standard). However, the code seems unreasonably bulky to me, even when I just started out.

I have split some of the code across various components, but my main container still spans over 140+ lines.
Is it possible to reduce the code size?


Here is the code

containers/standards.js

import React, { Component, PropTypes } from 'react';
import { connect } from 'react-redux';

import { createStandard, updateStandard, deleteStandard } from '../actions/standards';
import Form from '../components/Form';
import Table from '../components/Table';

class Standards extends Component {
  constructor(props) {
    super(props);

    this.standard = null;
    this.state = {
      shouldRenderForm: false,
    };

    this.renderForm = this.renderForm.bind(this);
    this.cancelForm = this.cancelForm.bind(this);

    this.createStandard = this.createStandard.bind(this);
    this.updateStandard = this.updateStandard.bind(this);

    this.deleteStandard = this.deleteStandard.bind(this);
    this.showStandard = this.showStandard.bind(this);
  }

  createStandard(e) {
    e.preventDefault();
    const standard = {
      id: e.target[0].value.trim(),
      year: e.target[1].value.trim(),
      section: e.target[2].value.trim(),
    };

    if (!(standard.year && standard.year)) {
      return;
    }

    this.setState({
      shouldRenderForm: false,
    });

    this.standard = null;
    this.props.createStandard(standard);
  }

  updateStandard(e) {
    e.preventDefault();

    const standard = {
      id: e.target[0].value.trim(),
      year: e.target[1].value.trim(),
      section: e.target[2].value.trim(),
    };

    if (!(standard.year && standard.year)) {
      return;
    }

    this.setState({
      shouldRenderForm: false,
    });

    this.standard = null;
    this.props.updateStandard(standard);
  }

  cancelForm() {
    this.setState({
      shouldRenderForm: false,
    });
  }

  showStandard() {
    // this.props.createStandard(standard);
  }

  deleteStandard(id) {
    if (this.standard.id === id) {
      this.setState({
        shouldRenderForm: false,
      });
    }
    this.props.deleteStandard(id);
  }

  renderForm(standard = null) {
    this.setState({
      shouldRenderForm: true,
    });

    if (standard === null) {
      this.standard = {};
      this.handleSubmit = this.createStandard;
    } else {
      this.standard = standard;
      this.handleSubmit = this.updateStandard;
    }
  }

  render() {
    return (
      <div ref="parent">
        <button onClick={() => { this.renderForm(); }}>NEW</button>
        {
          this.state.shouldRenderForm
          ? <Form
            standard={this.standard}
            handleSubmit={this.handleSubmit}
            cancelForm={this.cancelForm}
          />
          : null
        }

        <Table
          standards={this.props.standards}
          renderForm={this.renderForm}
          showStandard={this.showStandard}
          deleteStandard={this.deleteStandard}
        />
      </div>
    );
  }
}

Standards.propTypes = {
  createStandard: PropTypes.func.isRequired,
  updateStandard: PropTypes.func.isRequired,
  deleteStandard: PropTypes.func.isRequired,
  standards: PropTypes.array.isRequired,
};

const mapStateToProps = (state) => ({
  standards: state.standards,
});

const mapDispatchToProps = (dispatch) => ({
  createStandard: (standard) => { dispatch(createStandard(standard)); },
  updateStandard: (standard) => { dispatch(updateStandard(standard)); },
  deleteStandard: (id) => { dispatch(deleteStandard(id)); },
});

export default connect(mapStateToProps, mapDispatchToProps)(Standards);


components/table.js

import React, { PropTypes } from 'react';

import Row from './Row';

const Table = ({ standards, renderForm, showStandard, deleteStandard }) => (
  <table>
    <thead>
      <tr>
        <td>S. No.</td>
        <td>YEAR</td>
        <td>SECTION</td>
        <td colSpan={3}>ACTIONS</td>
      </tr>
    </thead>
    <tbody>
      {standards.map((s, i) => <Row
        key={`${s.year}-${s.section}`}
        idx={i}
        standard={s}
        renderForm={renderForm}
        showStandard={showStandard}
        deleteStandard={deleteStandard}
      />)}
    </tbody>
  </table>
);

Table.propTypes = {
  standards: PropTypes.array.isRequired,
  renderForm: PropTypes.func.isRequired,
  showStandard: PropTypes.func.isRequired,
  deleteStandard: PropTypes.func.isRequired,
};

export default Table;


components/row.js

import React, { PropTypes } from 'react';

const Row = ({ idx, standard, renderForm, showStandard, deleteStandard }) => (
  <tr>
    <td>{`${idx + 1}`}</td>
    <td>{`${standard.year}`}</td>
    <td>{`${standard.section}`}</td>
    <td><a href="#" onClick={showStandard}>SHOW</a></td>
    <td><a href="#" onClick={() => { renderForm(standard); }}>UPDATE</a></td>
    <td><a href="#" onClick={() => { deleteStandard(standard.id); }}>DELETE</a></td>
  </tr>
);

Row.propTypes = {
  idx: PropTypes.number.isRequired,
  standard: PropTypes.object.isRequired,
  renderForm: PropTypes.func.isRequired,
  showStandard: PropTypes.func.isRequired,
  deleteStandard: PropTypes.func.isRequired,
};

export default Row;


components/form.js

import React, { PropTypes } from 'react';

const Form = ({ standard, handleSubmit, cancelForm }) => (
  <form onSubmit={handleSubmit}>
    <input type="hidden" id="id" value={standard.id || +(new Date())} />
    <input type="text" id="year" placeholder="year" defaultValue={standard.year} />
    <input type="text" id="section" placeholder="section" defaultValue={standard.section} />
    <input type="submit" value="SUBMIT" />
    <input type="button" value="CANCEL" onClick={cancelForm} />
  </form>
);

Form.propTypes = {
  cancelForm: PropTypes.func.isRequired,
  handleSubmit: PropTypes.func.isRequired,
  standard: PropTypes.object.isRequired,
};

export default Form;


reducers/standards.js

import { STANDARDS } from '../actions/standards';

const initialState = [];

export default function standards(state = initialState, action) {
  switch (action.type) {
    case STANDARDS.CREATE:
      return [
        ...state,
        action.standard,
      ];

    case STANDARDS.UPDATE:
      return state.map((s) => {
        if (s.id !== action.standard.id) {
          return s;
        }
        return action.standard;
      });

    case STANDARDS.DELETE:
      return state.filter((s) => s.id !== action.id);

    default:
      return state;
  }
}


actions/standards.js

export const STANDARDS = {
  CREATE: 'CREATE_STANDARD',
  DELETE: 'DELETE_STANDARD',
  UPDATE: 'UPDATE_STANDARD',
};

export const createStandard = (standard) => ({
  type: STANDARDS.CREATE,
  standard,
});

export const updateStandard = (standard) => ({
  type: STANDARDS.UPDATE,
  standard,
});

export const deleteStandard = (id) => ({
  type: STANDARDS.DELETE,
  id,
});


index.js

import React from 'react';
import { createStore } from 'redux';
import { render } from 'react-dom';
import { Provider } from 'react-redux';

import reducer from './reducers';
import Standards from './containers/Standards';

const store = createStore(reducer);

render(
  <Provider store={store}>
    <Standards />
  </Provider>,
  document.querySelector('#react-root')
);
share|improve this question
    
As we all want to make our code more efficient or improve it in one way or another, try to write a title that summarizes what your code does, not what you want to get out of a review. – Jamal Apr 25 at 2:45
    
Well, first of all put your form preparations into the Form Component. And handleSubmit with the prepared data.. Because you are fetching the values from a child Component.. (Are you sure the Form Component will never change?) – webdeb Jun 20 at 12:25

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.