Advanced Go: Reflection, Generics, and Error Handling

#go
#golang
#advanced

Explore advanced concepts in Go language, including reflection, generics, and enhanced error handling:

Reflection

Reflection in Go allows you to inspect and modify the runtime type information. The reflect package provides tools to work with reflection:

package main

import (
    "fmt"
    "reflect"
)

func main() {
    var x float64 = 3.4
    v := reflect.ValueOf(x)
    fmt.Println("Type:", v.Type())
    fmt.Println("Kind:", v.Kind())
    fmt.Println("Value:", v.Float())
}

Generics

Go 1.18 introduces support for generics, which enables writing functions and data structures that can work with different types:

package main

import "fmt"

func PrintSlice[T any](s []T) {
    for _, v := range s {
        fmt.Println(v)
    }
}

func main() {
    intSlice := []int{1, 2, 3}
    stringSlice := []string{"Hello", "Go", "Generics"}

    PrintSlice[int](intSlice)
    PrintSlice[string](stringSlice)
}

Error Handling

Go 1.13 introduces enhanced error handling with error wrapping and unwrapping:

package main

import (
    "errors"
    "fmt"
)

func main() {
    err := fmt.Errorf("a new error: %w", errors.New("the root cause"))
    fmt.Println(err)

    var rootErr error
    if errors.As(err, &rootErr) {
        fmt.Println("Root error:", rootErr)
    }
}

These advanced concepts help improve the versatility and flexibility of your Go code.

React 18 useDeferredValue

#react
#react18

React 18 introduces useDeferredValue to defer the rendering of less important updates:

import { useState, useDeferredValue } from 'react';

function App() {
  const [text, setText] = useState('');
  const deferredText = useDeferredValue(text, { timeoutMs: 2000 });

  return (
    <div>
      <input
        type="text"
        value={text}
        onChange={(e) => setText(e.target.value)}
      />
      <SearchResults query={deferredText} />
    </div>
  );
}

export default App;

The useDeferredValue hook helps prioritize important updates and defer less critical ones, improving rendering performance.

Official Docs

React 18 useTransition

#react
#react18

React 18 introduces useTransition to manage loading states and prevent UI jank during state updates:

import { useState, useTransition } from 'react';

function App() {
  const [resource, setResource] = useState(null);
  const [startTransition, isPending] = useTransition();

  const handleClick = () => {
    startTransition(() => {
      setResource(fetchNewData());
    });
  };

  return (
    <div>
      <button onClick={handleClick}>
        {isPending ? 'Loading...' : 'Load Data'}
      </button>
      <DisplayResource resource={resource} />
    </div>
  );
}

export default App;

The useTransition hook helps create smoother user experiences during data fetching and state updates.

Official Docs

React 18 Automatic Batching of State Updates

#react
#react18

React 18 introduces automatic batching of state updates, resulting in more efficient rendering and fewer re-renders:

import { useState } from 'react';

function App() {
  const [count, setCount] = useState(0);
  const [text, setText] = useState('');

  const handleClick = () => {
    // In React 18, these updates are automatically batched
    setCount(count + 1);
    setText('Updated');
  };

  return (
    <div>
      <h1>{count}</h1>
      <p>{text}</p>
      <button onClick={handleClick}>Update</button>
    </div>
  );
}

export default App;

In React 18, state updates triggered within the same event handler are automatically batched, minimizing unnecessary re-renders and improving performance.

Official Docs

React 18 Server Components

#react
#react18

React 18 introduces Server Components, enabling you to build modern UIs with a server-rendered architecture:

  1. Create a server component:
// components/ServerComponent.server.jsx
import { useEffect } from 'react';
import { useFetch } from '@/useFetch';

export default function ServerComponent({ query }) {
  const data = useFetch(`/api/data?query=${query}`);

  useEffect(() => {
    // This effect will not run on the server
  }, []);

  return (
    <>
      <h1>Server Component</h1>
      <div>{data}</div>
    </>
  );
}
  1. Use the server component in a client component:
// components/ClientComponent.jsx
import ServerComponent from '@/ServerComponent.server';

export default function ClientComponent() {
  return (
    <>
      <h1>Client Component</h1>
      <ServerComponent query="example" />
    </>
  );
}

Server Components render on the server and send HTML to the client, improving performance and reducing bundle size.

Official Docs

Next.js API Routes with Middlewares

#nextjs
#react

Use middlewares to handle common tasks like authentication or request validation in your API routes:

// lib/withMiddleware.js
const withMiddleware = (handler) => (req, res) => {
  // Middleware logic
  if (!req.headers.authorization) {
    res.status(401).json({ message: 'Unauthorized' });
    return;
  }

  return handler(req, res);
};

export default withMiddleware;

// pages/api/secure-route.js
import withMiddleware from '@/lib/withMiddleware';

const handler = (req, res) => {
  res.status(200).json({ message: 'Secure route accessed' });
};

export default withMiddleware(handler);

This example shows how to create an API route with authentication middleware.

Official Docs

React Concurrent Mode

#react

Concurrent Mode enables React to work on multiple tasks without blocking the main thread:

TypeScript Mapped Types

#typescript

Mapped types allow you to create new types by transforming existing ones:

type Readonly<T> = {
  readonly [P in keyof T]: T[P];
};

interface Person {
  name: string;
  age: number;
}

const person: Readonly<Person> = {
  name: 'Alice',
  age: 30,
};

person.age = 31; // Error: Cannot assign to 'age' because it is a read-only property

The Readonly mapped type makes all properties of Person read-only.

Official Docs

GoLang Context Package

#golang

The context package in Go helps manage deadlines, cancelations, and request-scoped values across API boundaries:

package main

import (
  "context"
  "fmt"
  "time"
)

func longRunningTask(ctx context.Context) {
  select {
  case <-time.After(5 * time.Second):
    fmt.Println("Task completed")
  case <-ctx.Done():
    fmt.Println("Task canceled")
  }
}

func main() {
  ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
  defer cancel()

  go longRunningTask(ctx)

  time.Sleep(6 * time.Second)
  fmt.Println("Done!")
}

The context.WithTimeout function creates a context with a deadline.

Official Docs

Next.js Middleware

#nextjs
#react

Middleware allows you to run server-side code before rendering your Next.js pages:

// pages/_middleware.js
import { NextResponse } from 'next/server';

export function middleware(req, event) {
  if (req.url.startsWith('/restricted')) {
    return NextResponse.redirect('/login');
  }
  return NextResponse.next();
}

This example redirects unauthorized users to the login page.

Official Docs

React Profiler API

#react

The Profiler API measures the performance of React components:

import React, { Profiler } from 'react';

const onRender = (id, phase, actualDuration) => {

<TIL.Items date="2023-01-15">

<TIL.Item>

## TypeScript Type Guards

<TIL.ItemTags>
  <TIL.ItemTag>typescript</TIL.ItemTag>
</TIL.ItemTags>

Type guards allow you to narrow down the type of an object within a specific scope:

```ts
function isString(value: unknown): value is string {
  return typeof value === 'string';
}

const value: unknown = 'hello';

if (isString(value)) {
  console.log(value.toUpperCase()); // 'HELLO'
}

The value is string syntax defines a custom type guard function.

Official Docs

GoLang Concurrency with Goroutines

#golang

Goroutines are lightweight threads managed by the Go runtime, enabling concurrent execution:

package main

import (
  "fmt"
  "time"
)

func printNumbers() {
  for i := 1; i <= 5; i++ {
    time.Sleep(1 * time.Second)
    fmt.Printf("%d ", i)
  }
}

func main() {
  go printNumbers()
  time.Sleep(6 * time.Second)
  fmt.Println("Done!")
}

The go keyword creates a new goroutine.

Official Docs

Next.js Incremental Static Regeneration

#nextjs
#react

Incremental Static Regeneration (ISR) allows you to update static pages without rebuilding the entire site:

export async function getStaticProps() {
  const data = await fetchData();

  return {
    props: { data },
    revalidate: 60, // Time in seconds
  };
}

The revalidate key updates the static content after the specified time.

Official Docs