27
loading...
This website collects cookies to deliver better user experience
create-react-app
command-line utility to create a new React app comes with a /src
directory. The starting point of this default React app (index.js file) is situated in this directory. A common practice is to use the /src
directory as a familiar convention. That means all the different folders for components, pages, etc., are created inside this directory.└── /src
├── /assets
├── /components
├── /context
├── /hooks
├── /pages
├── /services
├── /utils
└── App.js
├── index.js
/services
directory can be called /api
./components
directory. Each component will live inside its own sub-directory. For example, if you are creating reusable Buttons, here is an example of a directory structure you can consider:└── /src
├── /components
| ├── /Button
| | ├── Button.js
| | ├── Button.styles.js
| | ├── Button.test.js
| | ├── Button.stories.js
| ├──index.js
Button
directory contains:Button.js
file that contains the actual React componentButton.styles.js
file, let's assume you are using styled components, contains corresponding stylesButton.test.js
file that contains testsButton.stories.js
the Storybook fileindex.js
file located in the /components
directory. In this scenario, this file acts as an index of all components that are part of the namesake directory. This file will look like the following:// /src/components/index.js
import { Button } from './Button/Button';
import { InputField } from './InputField/InputField';
import { Card } from './Card/Card';
export { Button, Card, InputField };
// /src/hooks/useTogglePasswordVisibility/index.js
export const useTogglePasswordVisibility = () => {
const [passwordVisibility, setPasswordVisibility] = useState(true);
const [rightIcon, setRightIcon] = useState('eye');
const handlePasswordVisibility = () => {
if (rightIcon === 'eye') {
setRightIcon('eye-off');
setPasswordVisibility(!passwordVisibility);
} else if (rightIcon === 'eye-off') {
setRightIcon('eye');
setPasswordVisibility(!passwordVisibility);
}
};
return {
passwordVisibility,
rightIcon,
handlePasswordVisibility
};
};
use
naming convention. Even though React isn't strict about naming conventions, it is important to follow them in this scenario. This hook also handles its own state and method and can be re-used on a password field, whether inside the login or a signup form./hooks
directory structure can be similar to components where a reusable hook lives inside their subdirectories:└── /src
├── /hooks
| ├── /useTogglePasswordVisibility
| | ├── index.js
| | ├── useTogglePasswordVisibility.test.js
| ├──index.js
// some file
import { Button } from '../../components';
jsconfig.json
file at the root of your project.jsconfig.json
file:{
"compilerOptions": {
"baseUrl": "src"
},
"include": ["src"]
}
/src/components
, you can import it as follows:import { Button } from 'components';
webpack.config.js
. In that case, you can customize this further to use a prefix like @components
or ~components
.module.exports = {
resolve: {
extensions: ['js'],
alias: {
'@': path.resolve(__dirname, 'src'),
'@components': path.resolve(__dirname, 'src/components')
'@hooks': path.resolve(__dirname, 'src/hooks'),
}
}
};
/src/components/Button
can be imported as:import { Button } from '@components';
tsconfig.json
. You can configure this file. For more information, check out Create React App documentation here./pages
directory will contain the UI for most of the application and the structure of each page in the form of React components. These components are naturally coupled with the business logic they represent. It is a common behavior that you will find in any React application. However, avoid unnecessary complexity in a UI component, you can separate the business logic from it.import { useQuery } from 'react-query';
export const moviesApi = {
nowPlaying: () =>
fetch(`${BASE_URL}/movie/now_playing?api_key=${API_KEY}&page=1`).then(res =>
res.json()
)
};
export const useNowPlayingMovies = () => {
const { isLoading: nowPlayingLoading, data: nowPlayingData } = useQuery(
['movies', 'nowPlaying'],
moviesApi.nowPlaying
);
return {
nowPlayingLoading,
nowPlayingData
};
};
/movie/now_playing
happens in two parts. The first part is the API request itself using JavaScript's fetch method that gets the data in JSON format. The second part is where the useQuery hook from React Query library is configured and wrapped inside a custom hook./hooks
directory or create another directory for API-related hooks such as /api
or /services
.utils
directory is completely optional. If your application tends to have some global utility functions, it could be a good idea to separate them from the UI components. A /utils
directory may contain app-wide constants and helper methods. For example, more than one UI component in your application may require some validation logic. Separating this validation business logic in its own file under the /utils
directory will help you create separate flows.const App = () => {
return (
<ThemeProvider>
<QueryClientProvider>
<Routes />
</QueryClientProvider>
</ThemeProvider>
)
}