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')
);
Form
Component. AndhandleSubmit
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