Until part 2, we have created a book search app and handled the loading and error state. Now we are going to see how we can split the app structure into components.
We have written the whole app in App.js
. It's still a small example, so there is no real need to split it into folders. This post will just showcase how to split the large applications without causing a mess to debug later on.
There are no common best practices for folder structure, it depends mainly on two factors
- How big is the project?
- How large is your team?
For large projects and large teams, feature or domain based folder structure will work well.
For small projects, file type based folder structure will work easily.
You can read more about it in react docs here
My personal opinion is to keep it simple, flat and scale only when you need. You should always refactor to sophisticated folder structure when each file grows in length.
Let's move on to the code,
In our books search application, we can create these components
- BookSearchForm
- Loader
- BooksList
- Books
Let's create a component folder and also create three JS files for our component.
// booksSearchForm.js
import React from 'react';
const BookSearchForm = ({
onSubmitHandler,
searchTerm,
onInputChange,
error,
}) => {
return (
<form onSubmit={onSubmitHandler}>
<label>
<span>Search for books</span>
<input
type="search"
placeholder="microservice, restful design, etc.,"
value={searchTerm}
onChange={onInputChange}
required
/>
<button type="submit">Search</button>
</label>
{error && (
<div style={{ color: `red` }}>
some error occurred, while fetching api
</div>
)}
</form>
);
};
export default BookSearchForm;
We have split the component into its own file and pass the necessary functions and state values as props.
Now in App.js
// App.js
import React, { useState } from 'react';
import axios from 'axios';
import BookSearchForm from './components/bookSearchForm';
import './App.css';
...
const App = () => {
...
return (
<section>
<BookSearchForm
onSubmitHandler={onSubmitHandler}
onInputChange={onInputChange}
searchTerm={searchTerm}
error={error}
/>
{
loading && <div style={{color: `green`}}>fetching books for "<strong>{searchTerm}</strong>"</div>
}
...
</section>
)
}
Lets split the other components as well in the same way.
// Loader.js
import React from 'react';
const Loader = ({ loading, searchTerm }) => {
return (
<>
{loading && (
<div style={{ color: `green` }}>
fetching books for "<strong>{searchTerm}</strong>"
</div>
)}
</>
);
};
export default Loader;
As for BooksList and Book component, I didn't split into files and put it in the same file. Will split it when the functionality grows.
// booksList.js
import React from 'react';
// Separate the UI specific transforming logic to utils folder
import { bookAuthors } from '../utils';
const Book = ({ book }) => {
return (
<li>
<div>
<img
alt={`${book.volumeInfo.title} book`}
src={`http://books.google.com/books/content?id=${
book.id
}&printsec=frontcover&img=1&zoom=1&source=gbs_api`}
/>
<div>
<h3>{book.volumeInfo.title}</h3>
<p>{bookAuthors(book.volumeInfo.authors)}</p>
<p>{book.volumeInfo.publishedDate}</p>
</div>
</div>
<hr />
</li>
);
};
const BooksList = ({ books }) => {
return (
<ul>
{books.items.map((book, index) => {
return <Book book={book} key={index} />;
})}
</ul>
);
};
export default BooksList;
And add all these together in App.js
return (
<>
<BookSearchForm
onSubmitHandler={onSubmitHandler}
onInputChange={onInputChange}
searchTerm={searchTerm}
error={error}
/>
<Loader searchTerm={searchTerm} loading={loading} />
<BooksList books={books} />
</>
);
That's it, folks, we have successfully split all our components. We can optimize it further by moving around states. That's for the next part.
We will see,
- how to manage state and
- Different ways to manage state (custom hooks, useReducer)
- why we are managing all state in App.js instead of the components itself in more detail
Checkout the codebase for this part 3 here and the whole series codebase can be referred here.
Stay in touch!
If you enjoyed this post, you can find me on Twitter for updates, announcements, and news. 🐤
Top comments (1)
I also like to read something new and prefer to download books in order to read a lot of new information. Recently, I was using pdfmania.com/ which is a pretty decent service where are represented a lot of various effective solutions in order how to download the book, what is the most interesting option and it is a good service.