Skip to content

Components

Functional components over class based components

Use functional components (see Reacts documentation) instead of class based components. When modifying existing class based components, rewriting them to be functional is preferred but not required.

Bad

1
2
3
4
5
class Welcome extends React.Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}

Good

1
2
3
const Welcome= () => ({name}) {
  return <h1>Hello, {name}</h1>;
}

Context API over Redux

Store global or multiple component state using the Context API vs in Redux.

Draft

This needs to be expanded with examples

Redux hooks

When it isn't possible to use the Context API, prefer to use Redux hooks instead of the existing mapStateToProps methods

Bad

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
const MyComponent = ({ startData, endDate }) => {
    return <h1>{startData} to {endDate}</h1>;
}

const mapStateToProps = (state) => {
    return {
        startDate: state.date.startDate,
        endDate: state.date.endDate,
    };
};

export default connect(mapStateToProps, null)(MyComponent);

Good

1
2
3
4
5
const MyComponent = () => {
    const startDate = useSelector(state => state.date.startDate);
    const endDate = useSelector(state => state.date.endDate);
    return <h1>{startData} to {endDate}</h1>
};

No Component suffix

Do not suffix components with Component.

Bad

1
2
<NavigationComponent />
<SidebarComponent />

Good

1
2
<Navigation />
<Sidebar />

Component filename casing

Bad

components/
|- myTable.js
|- MyGraph.js
|- mybutton.js

Good

components/
|- my-table.js
|- my-graph.js
|- my-button.js

Tightly coupled component names

Child components that are tightly coupled with their parent should include the parent component name as a prefix.

If a component only makes sense in the context of a single parent component, that relationship should be evident in its name. Since editors typically organize files alphabetically, this also keeps these related files next to each other.

See Vue's style guide for more information.

Bad

components/
|- TodoList.js
|- TodoItem.js
|- TodoButton.js

Good

components/
|- TodoList.js
|- TodoListItem.js
|- TodoListItemButton.js

Order of words in component names

Component names should start with the highest-level (often most general) words and end with descriptive modifying words.

See Vue's style guide for more information.

Bad

components/
|- ClearSearchButton.js
|- ExcludeFromSearchInput.js
|- LaunchOnStartupCheckbox.js
|- RunSearchButton.js
|- SearchInput.js
|- TermsCheckbox.js

Good

components/
|- SearchButtonClear.js
|- SearchButtonRun.js
|- SearchInputQuery.js
|- SearchInputExcludeGlob.js
|- SettingsCheckboxTerms.js
|- SettingsCheckboxLaunchOnStartup.js

Full-word component names

Component names should prefer full words over abbreviations.

The autocompletion in editors make the cost of writing longer names very low, while the clarity they provide is invaluable. Uncommon abbreviations, in particular, should always be avoided.

Bad

components/
|- SdSettings.js
|- UProfOpts.js

Good

components/
|- StudentDashboardSettings.js
|- UserProfileOptions.js

Importing components with same name

Ensure that components are imported with the same name . This makes a components usage easily searchable.

Bad

// primary-button.js
export Default PrimaryButton;

// page1.js
import Button from ‘./primary-button.js’

Good

// primary-button.js
export Default PrimaryButton;

// page1.js
import PrimaryButton from ‘./primary-button.js’;

Use performance features where possible

For components that render a lot of sub-components or HTML, or for functions that perform expensive computation, use performance improving features such as useMemo.

Components should not expose HTML event

Components should not expose HTML events directly, and instead just return the related value. For example if you had an input

If you need to do things such as event.preventDefault(), this should be configured via props instead

Bad

<Input onChange={(event) => {
    if(e.key === "Escape") {
        event.preventDefault();
    }
    console.log(event.target.value)
    } />

Good

<Input
    onChange={(value) => console.log(value)}
    captureEscape
    />