edifice.Component

class edifice.Component[source]

Bases: object

The base class for Edifice Components.

A Component is a stateful container wrapping a stateless render function. Components have both internal and external properties.

The external properties, props, are passed into the Component by another Component’s render function through the constructor. These values are owned by the external caller and should not be modified by this Component. They may be accessed via the field props (self.props), which is a PropsDict. A PropsDict allows iteration, get item (self.props[“value”]), and get attribute (self.props.value), but not set item or set attribute. This limitation is set to protect the user from accidentally modifying props, which may cause bugs. (Note though that a mutable prop, e.g. a list, can still be modified; be careful not to do so)

The internal properties, the state, belong to this Component, and may be used to keep track of internal state. You may set the state as attributes of the Component object, for instance self.my_state. You can initialize the state as usual in the constructor (e.g. self.my_state = {“a”: 1}), and the state persists so long as the Component is still mounted.

In most cases, changes in state would ideally trigger a rerender. There are two ways to ensure this. First, you may use the set_state function to set the state:

self.set_state(mystate=1, myotherstate=2)

You may also use the self.render_changes() context manager:

with self.render_changes():
    self.mystate = 1
    self.myotherstate = 2

When the context manager exits, a state change will be triggered. The render_changes() context manager also ensures that all state changes happen atomically: if an exception occurs inside the context manager, all changes will be unwound. This helps ensure consistency in the Component’s state.

Note if you set self.mystate = 1 outside the render_changes() context manager, this change will not trigger a re-render. This might be occasionally useful but usually is unintended.

The main function of Component is render, which should return the subcomponents of this component. These may be your own higher-level components as well as the core Components, such as Label, Button, and View. Components may be composed in a tree like fashion: one special prop is children, which will always be defined (defaults to an empty list). To better enable the visualization of the tree-structure of a Component in the code, the call method of a Component has been overriden to set the arguments of the call as children of the component. This allows you to write tree-like code remniscent of HTML:

View(layout="column")(
    View(layout="row")(
        Label("Username: "),
        TextInput()
    ),
    View(layout="row")(
        Label("Email: "),
        TextInput()
    ),
)

The render function is called when self.should_update(newprops, newstate) returns True. This function is called when the props change (as set by the render function of this component) or when the state changes (when using set_state or render_changes()). By default, all changes in newprops and newstate will trigger a re-render.

When the component is rendered, the render function is called. This output is then compared against the output of the previous render (if that exists). The two renders are diffed, and on certain conditions, the Component objects from the previous render are maintained and updated with new props.

Two Components belonging to different classes will always be re-rendered, and Components belonging to the same class are assumed to be the same and thus maintained (preserving the old state).

When comparing a list of Components, the Component’s _key attribute will be compared. Components with the same _key and same class are assumed to be the same. You can set the key using the set_key method, which returns the component to allow for chaining:

View(layout="row")(
    MyComponent("Hello").set_key("hello"),
    MyComponent("World").set_key("world"),
)

If the _key is not provided, the diff algorithm will assign automatic keys based on index, which could result in subpar performance due to unnecessary rerenders. To ensure control over the rerender process, it is recommended to set_keys whenever you have a list of children.

Methods

did_mount()

Callback function that is called when the component mounts for the first time.

did_render()

Callback function that is called whenever the component renders.

did_update()

Callback function that is called whenever the component updates.

register_props(props)

Register props.

register_ref(reference)

Registers provided reference to this component.

render()

Logic for rendering, must be overridden.

render_changes([ignored_variables])

Context manager for managing changes to state.

set_key(key)

Sets the key of the component.

set_state(**kwargs)

Set state and render changes.

should_update(newprops, newstate)

Determines if the component should rerender upon receiving new props and state.

will_unmount()

Callback function that is called when the component will unmount.

Attributes

children

The children of this component.

props

The props of this component.