Hello all,
It's been a while since I made Monkeytype clone in React. I wrote the whole app in the Class Components approach because I was a newbie at that time, and it was the easiest way to make a React app. But after some time, I understood why it's not the best approach.
Why functional instead of class?
In Class-based components, You can't use one component's function in other component because it integrates functionality with UI very tightly.
States in class-based components are mutated using this.setState()
. Some of you might have observed the problem here. For others, "this" is the problem. It prevents/makes it hard to mutate the state when the helper function is not in the same scope.
Class-based components causes the following issues:
Lesser Reusability
For example, If we have counterIncrement function in a class component. It'll definitely use this.setState() to increase the counter. We can't use that counterIncrement in any other component because it's bound to that class only.
Duplication
We have to write same counterIncrement function in all the other components or pass it somehow as a props and that creates lots of duplicate code everywhere.
Increased Complexity
Just because we're passing and creating functions it creates confusion that what function is doing what.
Beginning of the journey
Recently, I re-wrote the entire app using Function Components. I noticed that I was passing so many states as props.
Result component before state management:
<Result
words={this.words}
typedHistory={this.state.typedHistory}
timeLimit={this.state.timeLimit}
spaces={this.words.indexOf(this.state.currWord)}
resetTest={() => this.resetTest()}
/>
At that point, I knew that I required a state management library. So I chose redux because it was co-developed by React team members. It made everything super easy to manage. On the other hand, I had to re-write every core function to integrate redux in the app.
Result component after state management:
<Result />
Looks so clean ✨.
So, How I'm passing props now? Answer to that is useSelector()
hook from react-redux library. It makes fetching state from any component piece of cake.
Redux word seems scary, but it's not even that horrifying if you know what you're doing. I enjoyed working with the react-redux library. There were some hiccups due to typescript, but everything else worked as expected.
Also, I noticed some performance gain after switching to the functional approach. It might be just a placebo, but the typing-test feels much smoother than before.
I encourage people to use the functional approach when making any react app. It will make your code easy to maintain in the long run.
You can check out the new and fresh typing-test code here:
salmannotkhan / typing-test
Typing test website build with React
typing-test
NOTE: This is my recreation of already existing monkeytype
This site is currently live: Visit Here
How to run locally
git clone https://github.com/salmannotkhan/typing-test.git
cd typing-test
npm install
npm start # to start local server at `localhost:3000`
npm run build # to create production build run
Got new ideas?
Did you know? You can add your theme and wordlist ideas into typing-test.
Here is how you can do it:
To add new theme:
- Add theme colors into
src/stylesheets/themes.scss
in following format:
.theme-name {
--bg-color: background-color;
--font-color: font-color;
--hl-color: highlight-color;
--fg-color: forground-color;
}
Note:
highlight-color
is used for caret, wrong characters, timer, selected and onhover colors
forground-color
is used for correctly typed characters
Using hex codes for colors is recommended
To add new wordlist:
- Rename your wordlist as
<wordlist-name>.json
and place it insidesrc/wordlists
.
Important:
The JSON file should…
Previous Article:
Top comments (0)