Props

Props (short for “properties”) are how data flows from parent to child components. They are read-only and help make components reusable.

Basic Usage

Pass props to a component:

from pyreact import element

def Greeting(props):
    name = props.get('name', 'World')
    return element('h1', {}, f'Hello, {name}!')

# Pass props
element(Greeting, {'name': 'PyReact'})

Props are Read-Only

Components must never modify their own props:

❌ Wrong
def Greeting(props):
    props['name'] = 'Modified'  # Never do this!
    return element('h1', {}, f'Hello, {props["name"]}')
✅ Correct
def Greeting(props):
    name = props.get('name', 'World')
    return element('h1', {}, f'Hello, {name}')

Default Props

Provide default values for props:

def Button(props):
    text = props.get('text', 'Click me')
    variant = props.get('variant', 'primary')
    disabled = props.get('disabled', False)

    return element('button', {
        'class': f'btn btn-{variant}',
        'disabled': disabled
    }, text)

# Usage
element(Button, {})  # Uses defaults
element(Button, {'text': 'Submit', 'variant': 'success'})

Children Prop

Pass children to components:

def Card(props):
    title = props.get('title', '')
    children = props.get('children', [])

    return element('div', {'class': 'card'},
        element('h2', {'class': 'card-title'}, title),
        element('div', {'class': 'card-body'}, *children)
    )

# Usage
element(Card, {'title': 'Welcome'},
    element('p', {}, 'This is the card content'),
    element('button', {}, 'Click me')
)

Prop Types

Props can be any Python type:

def UserCard(props):
    user = props['user']  # dict
    on_click = props['onClick']  # function
    is_active = props.get('active', False)  # bool
    tags = props.get('tags', [])  # list

    return element('div', {'class': 'user-card'},
        element('h3', {}, user['name']),
        element('p', {}, f"Active: {is_active}"),
        element('div', {},
            *[element('span', {'class': 'tag'}, tag) for tag in tags]
        ),
        element('button', {'onClick': on_click}, 'View Profile')
    )

Passing Functions as Props

Pass callback functions to child components:

class Parent(Component):
    def __init__(self, props):
        super().__init__(props)
        self.state = {'count': 0}

    def handle_increment(self, amount):
        self.setState({'count': self.state['count'] + amount})

    def render(self):
        return element('div', {},
            element('p', {}, f'Count: {self.state["count"]}'),
            element(ChildButton, {
                'onClick': lambda e: self.handle_increment(1),
                'label': 'Add 1'
            }),
            element(ChildButton, {
                'onClick': lambda e: self.handle_increment(10),
                'label': 'Add 10'
            })
        )

Best Practices

  1. Use descriptive prop names - is_active instead of active

  2. Provide defaults - Use props.get() with default values

  3. Document props - Add docstrings explaining expected props

  4. Validate props - Check required props exist

Next Steps