Hooks API

Hooks let you use state and other features in function components.

useState

useState(initial_value)

Adds state to a function component.

Parâmetros:

initial_value (any) – Initial state value

Retorna:

Tuple of (current_value, setter_function)

Tipo de retorno:

tuple

Example:

from pyreact import element, useState

def Counter(props):
    count, set_count = useState(0)

    def increment():
        set_count(count + 1)

    return element('div', {},
        element('p', {}, f'Count: {count}'),
        element('button', {'onClick': increment}, 'Increment')
    )

Functional updates:

def Counter(props):
    count, set_count = useState(0)

    def increment():
        # Use function for derived state
        set_count(lambda prev: prev + 1)

    return element('button', {'onClick': increment}, f'Count: {count}')

useEffect

useEffect(effect, dependencies=None)

Performs side effects in function components.

Parâmetros:
  • effect (callable) – Function to run (can return cleanup function)

  • dependencies (list, optional) – Array of values that trigger the effect

Example:

from pyreact import element, useState, useEffect

def DataFetcher(props):
    data, set_data = useState(None)
    loading, set_loading = useState(True)

    def fetch_data():
        # Fetch data
        set_data(fetch_from_api())
        set_loading(False)

    # Run once on mount
    useEffect(fetch_data, [])

    if loading:
        return element('div', {}, 'Loading...')

    return element('div', {}, f'Data: {data}')

With cleanup:

def Timer(props):
    seconds, set_seconds = useState(0)

    def setup_timer():
        timer_id = setInterval(lambda: set_seconds(s => s + 1), 1000)

        # Cleanup function
        return lambda: clearInterval(timer_id)

    useEffect(setup_timer, [])

    return element('div', {}, f'Seconds: {seconds}')

With dependencies:

def UserProfile(props):
    user_id = props['userId']
    user, set_user = useState(None)

    def fetch_user():
        set_user(fetch_user_by_id(user_id))

    # Re-run when userId changes
    useEffect(fetch_user, [user_id])

    return element('div', {}, f'User: {user}')

useContext

useContext(context)

Accesses context value.

Parâmetros:

context (Context) – Context object created by createContext

Retorna:

Current context value

Tipo de retorno:

any

Example:

from pyreact import element, createContext, useContext

ThemeContext = createContext('light')

def ThemedButton(props):
    theme = useContext(ThemeContext)

    return element('button', {
        'style': {'backgroundColor': theme['primary']}
    }, 'Click me')

useRef

useRef(initial_value=None)

Creates a mutable reference that persists across renders.

Parâmetros:

initial_value (any, optional) – Initial ref value

Retorna:

Ref object with current property

Tipo de retorno:

Ref

Example:

from pyreact import element, useRef

def TextInput(props):
    input_ref = useRef()

    def focus():
        input_ref.current.focus()

    return element('div', {},
        element('input', {'ref': input_ref}),
        element('button', {'onClick': focus}, 'Focus')
    )

useMemo

useMemo(factory, dependencies)

Memoizes expensive computations.

Parâmetros:
  • factory (callable) – Function that computes the value

  • dependencies (list) – Values that trigger recomputation

Retorna:

Memoized value

Tipo de retorno:

any

Example:

from pyreact import element, useMemo

def ExpensiveList(props):
    items = props['items']
    filter_text = props['filter']

    # Only recompute when items or filter changes
    filtered_items = useMemo(
        lambda: [i for i in items if filter_text in i['name']],
        [items, filter_text]
    )

    return element('ul', {},
        *[element('li', {'key': i['id']}, i['name'])
          for i in filtered_items]
    )

useCallback

useCallback(callback, dependencies)

Returns a memoized callback.

Parâmetros:
  • callback (callable) – Function to memoize

  • dependencies (list) – Values that trigger recreation

Retorna:

Memoized callback

Tipo de retorno:

callable

Example:

from pyreact import element, useCallback

def Parent(props):
    def handle_click(item_id):
        print(f'Clicked: {item_id}')

    # Memoize callback
    memoized_click = useCallback(handle_click, [])

    return element('div', {},
        *[element(ChildButton, {
            'key': item['id'],
            'id': item['id'],
            'onClick': memoized_click
        }) for item in props['items']]
    )

useReducer

useReducer(reducer, initial_state, init=None)

Alternative to useState for complex state logic.

Parâmetros:
  • reducer (callable) – Function (state, action) => new_state

  • initial_state (any) – Initial state value

  • init (callable, optional) – Lazy initialization function

Retorna:

Tuple of (state, dispatch)

Tipo de retorno:

tuple

Example:

from pyreact import element, useReducer

def reducer(state, action):
    if action['type'] == 'increment':
        return {'count': state['count'] + 1}
    elif action['type'] == 'decrement':
        return {'count': state['count'] - 1}
    elif action['type'] == 'reset':
        return {'count': action['payload']}
    return state

def Counter(props):
    state, dispatch = useReducer(reducer, {'count': 0})

    return element('div', {},
        element('p', {}, f'Count: {state["count"]}'),
        element('button', {
            'onClick': lambda: dispatch({'type': 'increment'})
        }, '+'),
        element('button', {
            'onClick': lambda: dispatch({'type': 'decrement'})
        }, '-'),
        element('button', {
            'onClick': lambda: dispatch({'type': 'reset', 'payload': 0})
        }, 'Reset')
    )

Custom Hooks

Create custom hooks:

from pyreact import useState, useEffect

def useLocalStorage(key, initial_value):
    """Custom hook for localStorage"""
    stored = localStorage.getItem(key)
    value, set_value = useState(stored or initial_value)

    def save_to_storage():
        localStorage.setItem(key, value)

    useEffect(save_to_storage, [value])

    return value, set_value

# Usage
def App(props):
    name, set_name = useLocalStorage('name', 'Guest')

    return element('input', {
        'value': name,
        'onChange': lambda e: set_name(e.target.value)
    })

Best Practices

  1. Only call hooks at the top level - Not inside loops or conditions

  2. Only call hooks from function components - Not from regular functions

  3. Use the dependency array - Specify all dependencies

  4. Name custom hooks with “use” - Convention for custom hooks

Next Steps