Back to all posts

Key Web Development Skills I've Gained Through My Projects

2024-03-20

Web Development
Throughout my journey as a web developer, I've had the opportunity to work on a variety of projects that have significantly enhanced my skill set. In this post, I'll share some of the key skills I've gained and how they've been applied in real-world scenarios.

1. Mastering React Hooks

One of the most transformative skills I've developed is proficiency with React Hooks. Through projects like my portfolio website and various client applications, I've learned to leverage hooks to create more efficient and readable code.

Example: Custom useLocalStorage Hook

import { useState, useEffect } from 'react'; function useLocalStorage(key, initialValue) { const [storedValue, setStoredValue] = useState(() => { try { const item = window.localStorage.getItem(key); return item ? JSON.parse(item) : initialValue; } catch (error) { console.log(error); return initialValue; } }); useEffect(() => { window.localStorage.setItem(key, JSON.stringify(storedValue)); }, [key, storedValue]); return [storedValue, setStoredValue]; }
This custom hook has been invaluable in managing local storage across my applications, providing a clean and reusable solution for persisting data.

2. Next.js and Server-Side Rendering

Working with Next.js has dramatically improved my understanding of server-side rendering (SSR) and static site generation (SSG). These skills have been crucial in developing high-performance, SEO-friendly websites.

Example: Dynamic Routes with getStaticProps and getStaticPaths

export async function getStaticPaths() { const paths = getAllPostIds(); return { paths, fallback: false }; } export async function getStaticProps({ params }) { const postData = await getPostData(params.id); return { props: { postData } }; } export default function Post({ postData }) { return ( <Layout> <Head> <title>{postData.title}</title> </Head> <article> <h1>{postData.title}</h1> <div dangerouslySetInnerHTML={{ __html: postData.contentHtml }} /> </article> </Layout> ); }
This pattern has been essential in creating dynamic, pre-rendered pages for blogs and e-commerce sites.

3. API Integration and Data Fetching

Developing full-stack applications has honed my skills in API integration and efficient data fetching. I've worked with RESTful APIs and GraphQL, implementing best practices for data management.

Example: Using SWR for Data Fetching

import useSWR from 'swr'; const fetcher = (...args) => fetch(...args).then(res => res.json()); function Profile() { const { data, error } = useSWR('/api/user', fetcher); if (error) return <div>Failed to load</div>; if (!data) return <div>Loading...</div>; return <div>Hello {data.name}!</div>; }
Using SWR has greatly improved the user experience in my applications by providing real-time, cached data fetching.

4. Responsive Design with Tailwind CSS

Adopting Tailwind CSS has revolutionized my approach to creating responsive, customizable user interfaces. It's become an integral part of my development process, allowing for rapid prototyping and consistent design implementation.

Example: Responsive Navigation

<nav className="flex items-center justify-between flex-wrap bg-teal-500 p-6"> <div className="flex items-center flex-shrink-0 text-white mr-6"> <span className="font-semibold text-xl tracking-tight">My Portfolio</span> </div> <div className="block lg:hidden"> <button className="flex items-center px-3 py-2 border rounded text-teal-200 border-teal-400 hover:text-white hover:border-white"> <svg className="fill-current h-3 w-3" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><title>Menu</title><path d="M0 3h20v2H0V3zm0 6h20v2H0V9zm0 6h20v2H0v-2z"/></svg> </button> </div> <div className="w-full block flex-grow lg:flex lg:items-center lg:w-auto"> <div className="text-sm lg:flex-grow"> <a href="#responsive-header" className="block mt-4 lg:inline-block lg:mt-0 text-teal-200 hover:text-white mr-4"> Home </a> <a href="#responsive-header" className="block mt-4 lg:inline-block lg:mt-0 text-teal-200 hover:text-white mr-4"> Projects </a> <a href="#responsive-header" className="block mt-4 lg:inline-block lg:mt-0 text-teal-200 hover:text-white"> Contact </a> </div> </div> </nav>
This responsive navigation component adapts seamlessly to different screen sizes, enhancing the overall user experience across devices.

5. State Management with Redux Toolkit

For larger applications, I've incorporated Redux Toolkit to manage complex state logic. This has improved the scalability and maintainability of my projects.

Example: Creating a Redux Slice

import { createSlice } from '@reduxjs/toolkit'; export const counterSlice = createSlice({ name: 'counter', initialState: { value: 0, }, reducers: { increment: (state) => { state.value += 1; }, decrement: (state) => { state.value -= 1; }, incrementByAmount: (state, action) => { state.value += action.payload; }, }, }); export const { increment, decrement, incrementByAmount } = counterSlice.actions; export default counterSlice.reducer;
This Redux Toolkit slice simplifies state management, making it easier to handle complex data flows in larger applications.

Conclusion

These skills represent just a fraction of what I've learned through my projects. Each new challenge has provided an opportunity to expand my knowledge and improve my craft. As I continue to grow as a developer, I look forward to tackling new technologies and solving increasingly complex problems in the world of web development.