If you like this project please support it with a star on Github 🌟
This is a specification to enforce structure for React components
npm install --save react-component-structure
yarn add react-component-structure
This component structure is used for separation of concerns. When you create a folder for your React component you have to follow the following structure:
-| Component
-| index.ts
-| logic.ts
-| render.tsx
-| style.ts
-| types.ts
Index file is just an assembly of all the parts of the component:
import { createComponent } from 'react-component-structure';
import useLogic from './logic';
import useRender from './render';
import useStyle from './style';
const Component = createComponent({ useLogic, useRender, useStyle });
export default Component;Logic file is a controller for the component with all the business logic hooks inside:
import { useCallback, useState } from 'react';
import type { Props } from './types';
const useLogic = (props: Props) => {
const [count, setCount] = useState(props.defaultCount);
const onClickMinus = useCallback(() => setCount((c) => c - 1), []);
const onClickPlus = useCallback(() => setCount((c) => c + 1), []);
return {
count,
onClickMinus,
onClickPlus,
};
};
export default useLogic;Render file is a JSX rendering the component:
import type { Props } from './types';
import type useLogic from './logic';
import type useStyle from './style';
const useRender = (props: Props, logic: ReturnType<typeof useLogic>, style: ReturnType<typeof useStyle>) => {
return (
<div>
<div style={style.title}>Hello {props.greeting}!</div>
<div style={style.counter}>Count: {logic.count}</div>
<div onClick={logic.onClickMinus}>Decrease</div>
<div onClick={logic.onClickPlus}>Increase</div>
</div>
);
};
export default useRender;Style file is a file with styles:
import type { Props } from './types';
import useLogic from './logic';
import { useMemo } from 'react';
const useStyle = (props: Props, logic: ReturnType<typeof useLogic>) =>
useMemo(
() => ({
counter: {
fontSize: logic.count + 10,
},
title: {
color: props.color,
},
}),
[logic.count, props.color],
);
export default useStyle;Here you can use any type of styles you want. It can be inline styles, styled components, Tailwind of whatever. The main goal is to keep everything related to styling in this file but not in render.tsx
Types file contains the input props interface of the component:
export interface Props {
color: string;
defaultCount: number;
greeting: string;
}