In web development, code reuse and logic encapsulation are crucial for building efficient, scalable, and maintainable applications. In this article, we'll take a deep dive into the approaches used by Vue 3 and React to implement these concepts, and explore the advantages and disadvantages of each.
Vue 3 Approach
Composition API and Vuex
<template>
<div>
<h1>{{title}}</h1>
<p>{{message}}</p>
</div>
</template>
<script>
import { ref, computed, watch } from 'vue';
export default {
setup() {
const title = ref('Hello World');
const message = computed(() => `This is a message: ${title.value}`);
watch(title, (newValue, oldValue) => {
console.log(`title changed from ${oldValue} to ${newValue}`);
});
return {
title,
message
};
}
};
</script>
With Vuex, you can manage the global state in a centralized store and share it across multiple components in your application. Here's an example of how to use Vuex to manage the state in a Vue 3 application:
// store.js
import { createStore } from 'vuex';
export default createStore({
state: {
count: 0
},
mutations: {
increment(state) {
state.count++;
}
}
});
// App.vue
<template>
<div>
<h1>{{count}}</h1>
<button @click="incrementCount">Increment</button>
</div>
</template>
<script>
import store from './store';
export default {
setup() {
const { count } = store.state;
const incrementCount = () => store.commit('increment');
return {
count,
incrementCount
};
}
};
</script>
Advantages
- Ease of use: Vue's composable functions are simple to use and understand, making it easy to implement code reuse and logic encapsulation in your applications.
- Reusability: Composable functions make it easy to share and reuse code across different components. This can reduce the amount of duplicated code in your applications and make it easier to maintain.
- Flexibility: Vue's composable functions can be used in a variety of different ways, making it easy to find a solution that fits your specific use case.
- Testability: The modular nature of composable functions makes it easier to write tests for your code, as you can test individual functions in isolation.
Disadvantages
- Steep learning curve: For developers who are not familiar with Vue, the composable function API may take some time to get used to.
- Limited community support: Although Vue is growing in popularity, it still has a smaller community than React, which may result in limited resources and support for some advanced use cases.
React Approach
Custom Hooks and Context API
import React, { useState, useEffect, useCallback } from 'react';function useModal(initialState = false) {const [isOpen, setIsOpen] = useState(initialState);const openModal = useCallback(() => setIsOpen(true), []);const closeModal = useCallback(() => setIsOpen(false), []);return { isOpen, openModal, closeModal };}function Modal({ children }) {const { isOpen, closeModal } = useModal();if (!isOpen) {return null;}return (<div className="modal-overlay"><div className="modal-content"><button onClick={closeModal}>Close</button>{children}</div></div>);}function ModalButton() {const { isOpen, openModal } = useModal();return (<><button onClick={openModal}>Open Modal</button>{isOpen && <Modal>This is a modal</Modal>}</>);}
The custom hook `useModal` encapsulates the state for whether the modal is open or not, as well as the functions for opening and closing the modal. The `Modal` component receives the `isOpen` state and the `closeModal` function as props and uses them to display the modal when `isOpen` is `true`, and hide the modal when `isOpen` is `false`. The `ModalButton` component uses the `useModal` hook and triggers the modal to open when the button is clicked.
import React, { useState, useContext, createContext } from 'react';// Create a context for the modal stateconst ModalContext = createContext({isModalOpen: false,toggleModal: () => {}});// Custom hook for managing the modal statefunction useModal() {const [isModalOpen, setIsModalOpen] = useState(false);function toggleModal() {setIsModalOpen(!isModalOpen);}return { isModalOpen, toggleModal };}// Modal component that will be used throughout the appfunction Modal({ children }) {const { isModalOpen, toggleModal } = useContext(ModalContext);if (!isModalOpen) {return null;}return (<div style={{ position: 'fixed', top: '50%', left: '50%', transform: 'translate(-50%, -50%)' }}><button onClick={toggleModal}>Close</button>{children}</div>);}// Button component that triggers the modalfunction TriggerModalButton() {const { toggleModal } = useContext(ModalContext);return (<button onClick={toggleModal}>Open Modal</button>);}// App component that provides the modal state through contextfunction App() {const modalState = useModal();return (<ModalContext.Provider value={modalState}><TriggerModalButton /><Modal><h2>Hello from the modal!</h2></Modal></ModalContext.Provider>);}
In this example, we created a `ModalContext` that holds the state for the modal (whether it's open or not) and a function to toggle it. Then, we created a custom hook `useModal` that manages the state of the modal. We also created a `Modal` component that displays the modal when its `isModalOpen` state is `true`, and a `TriggerModalButton` component that triggers the modal by calling `toggleModal`. Finally, the `App` component provides the modal state through context using the `ModalContext.Provider`. Now, any component within the `App` component can access the modal state and toggle it using the `ModalContext`.
With custom hooks and the Context API, React provides a flexible and powerful way to handle code reuse and logic encapsulation.
Advantages
- Reusability: Custom hooks make it easy to share and reuse stateful logic across different components, reducing duplicated code and making your applications easier to maintain.
- Testability: The modular nature of custom hooks makes it easier to write tests for your code, as you can test individual hooks in isolation.
- Flexibility: Custom hooks and the Context API can be used in a variety of different ways, making it easy to find a solution that fits your specific use case.
- Large community: React has a large and active community of developers, which means you have access to a wide range of resources and support for advanced use cases.
Disadvantages
- Steep learning curve: For developers who are new to React, custom hooks and the Context API may take some time to get used to.
- Complexity: While custom hooks and the Context API are very powerful, they can also add a layer of complexity to your code, making it more difficult to understand and maintain.