Creating a Memory Card Game Using JavaScript React Hooks in Functional Components
In order to dial-in my React skills, I created a memory card application. For this project I used functional components instead of classes.
I completed this project as an assignment in the full-stack developer curriculum at theOdinProject. I chose the theme of popular car make logos.
React State
React state is essentially a way of storing data that will likely be manipulated during the user’s browser session. Manipulating this data typically results in the screen being re-rendered.
Managing React State through Classes
The original way of of handling state was through classes. The following is an example of a React class with state:
class App extends Component {
constructor() {
super();
this.state = {
generalData: {
fullName: '',
emailAddress: '',
linkedIn: '',
id: uniqid(),
}
}
}
handleChangeGeneral = (e) => {
this.setState((prevState) => {
return {
generalData: {
...prevState,
[e.target.name]: e.target.value,
}
}
});
};
};
Managing React State through Functional Components
Starting with React 16.8, developers can now manage state through functional components, like this:
const App = props => {
const [generalData, setGeneralData] = useState({
fullName: '',
phoneNumber: '',
emailAddress: '',
linkedIn: '',
id: uniqid(),
});
};
const handleChangeGeneral = e => {
setGeneralData(prevState => {
return { ...prevState, [e.target.name]: e.target.value }
})
}
React functional components are easier to read and test than class components.
Developers can implement state through the use of hooks. Hooks allow accessing React state and lifecycle features without using classes.
What I Learned about React Hooks
I found that React Hooks simplify the development process. The code is easier to read and write.
I also learned that useEffect is the functional component equivalent of the following class lifecycle methods:
- componentDidMount
- componentDidUpdate
- componentWillUnmount
I utilized useEffect to update the top score state of my app:
const [highScore, setHighScore] = useState(0);
useEffect(() => {
return score > highScore ? setHighScore(score) : null;
}, [score, highScore]);
Notice the second argument in useEffect. I only want to fire this effect when score or highScore have updated. That is what the second argument is for.
The second argument can be useful to prevent an infinite loop in some situations.
Links
Visit my github repository to see the original source code for this project.