A. Introduction
User interfaces or components are basically just the elements of an HTML. An element is consisted of three parts, a start tag, a content and an end tag. An element may also contain an attribute to enhance it.Here is an example of an HTML element.
<h3 style="color: red;">ReactPy</h3>
The h3 is the tag. This element has a ReactPy content. It also has a style attribute which is comprised of property name color
and property value red
responsible for turning the text color to red.
Here is an example of a button element that has an onclick event attribute.
<button type="button" onclick="alert('Hello world!')">Click Me!</button>
In its basic form, ReactPy component is just an html element wrapped in a function with component
decorator.
@component def BasicComponent(): return html.h3('ReactPy')
In section C, we will be generating some ReactPy components from sample application. Importing component from other module is also covered.
B. Different kinds of tags
HTML has more than 100 tags. This includes but is not limited to <html>, <body>, <h1>, <img>, <a>, <head>, <div>, and others.Below is a simple example demonstrating the utilization of tags in an HTML page.
<!DOCTYPE html> <html lang="en"> <head> <title>Title of the article</title> </head> <body> <h1>A header tag with size 1</h1> <p>A paragraph tag.</p> </body> </html>
The element with title is a component in React and ReactPy. The element with head is also a component that is composed of an element with title
. The head
is the parent component of title
and the title
is the child of head
.
The element with tag body has 2 children. They are the header <h1> and paragraph <p>.
C. Creating component with ReactPy
Component is created with a Python function decorated with a component
. Components should be designed so that it can be reused in other applications.
1. Sample components and usage
Let us create a Title
, TitleDescription
, and Home
components. We will call them at certain location in our code and render a page.
@component def Title(): return html.h1("Create component using ReactPy")
@component def TitleDescription(): return html.p("ReactPy component can be created by composing \ a function that will return an html element.")
Our root component Home. It just calls other components.
@component def Home(): return html.div( Title(), TitleDescription() )
Here is the full code along with some imports and entry point. Note we use the fastapi backend.
title.pyfrom reactpy import component, html from reactpy.backend.fastapi import configure from fastapi import FastAPI @component def Title(): return html.h1("Create component using ReactPy") @component def TitleDescription(): return html.p("ReactPy component can be created by composing \ a function that will return an html element.") @component def Home(): return html.div( Title(), TitleDescription(), ) app = FastAPI() configure(app, Home)
We can run this code with the following command line.
uvicorn title:app
Be sure you have already installed python and ReactPy or read the guide on how to install reactpy.
Typical console output.
INFO: Will watch for changes in these directories: ['C:\\myreactpyproject'] INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) INFO: Started reloader process [9540] using WatchFiles INFO: Started server process [11640] INFO: Waiting for application startup. INFO: Application startup complete. INFO: ('127.0.0.1', 53348) - "WebSocket /_reactpy/stream" [accepted] INFO: connection open
Open your web browser such as google chrome and paste http://127.0.0.1:8000
in the address bar.
a. Improve code for Reusability
We can improve the existing code by adding parameters for Title()
and TitleDescription()
to make it more reusable. Our latest title.py module is this.
from reactpy import component, html from reactpy.backend.fastapi import configure from fastapi import FastAPI @component def Title(title): return html.h1(title) @component def TitleDescription(description): return html.p(description) @component def Home(): title = "Create component using ReactPy" description = "ReactPy component can be created by composing \ a function that will return an html element." return html.div( Title(title), TitleDescription(description), ) app = FastAPI() configure(app, Home)
The component Title
and TitleDescription
have now a title and a description parameters respectively.
By modifying the title
and description
values, the revision would permit the utilization of Title
and TitleDescription
components in other modules through imports.
b. Importing component from other module
Here is a case, use the Title component from title.py file or module into the todo.py module in Todo application. Note this is not a realistic Todo App, it is just a demo to demonstrate importing component.
todo.pyfrom reactpy import component, html from reactpy.backend.fastapi import configure from fastapi import FastAPI from title import Title # this one @component def Todo(): todo_title = "Todo Application" return html.div( Title(todo_title), # imported from title.py module html.ol( html.li('Study React'), html.li('Study ReactPy'), ) ) app = FastAPI() configure(app, Todo)
This is the result after executing the command.
uvicorn todo:app
So we got the todo_title
displayed using the Title component
from title.py module.
2. Random number generator
Let us build a simple random number generator web application. The user will press the button and random number will be printed. This also features how to define a function that triggers after pressing the button and how to manage a variable using use_state() hook.
randomnumber.pyimport random from reactpy import component, html, hooks from reactpy.backend.fastapi import configure from fastapi import FastAPI RANDOM_NUMBER_INIT_VALUE = 0 BUTTON_TEXT = 'Generate Random Number' MIN_NUM = 0 MAX_NUM = 1000 @component def RandomNumbers(): random_number, set_random_number = hooks.use_state(RANDOM_NUMBER_INIT_VALUE) def generate_random_number(event): # Update the value of the random_number variable. set_random_number(random.randint(MIN_NUM, MAX_NUM)) return html.div( html.button({'on_click': generate_random_number}, BUTTON_TEXT), # Display the random number. html.p(f'random number is {random_number}') ) app = FastAPI() configure(app, RandomNumbers)
Run the application.
uvicorn randomnumber:app
You will get something like this after pressing the button.
We can apply styling on the div tag so that the button and text will be centered on the page.
return html.div( {'style': {'text-align': 'center'}}, # this line html.button({'on_click': generate_random_number}, BUTTON_TEXT), # Display the random number. html.p(f'random number is {random_number}') )
3. BMI (Body Mass Index) Application
This application features the input and button components as well as use_state() hook. User will enter the height in meters and weight in kilograms. BMI is calculated after the button is pressed.
bmi.pyfrom reactpy import component, html, hooks from reactpy.backend.fastapi import configure from fastapi import FastAPI @component def BMI(): height, set_height = hooks.use_state('') weight, set_weight = hooks.use_state('') bmi, set_bmi = hooks.use_state(0) def get_bmi(event): if height == '' or weight == '': return cal_bmi = float(weight) / (float(height) * float(height)) set_bmi(cal_bmi) return html.div( {'style': {'display': 'flex', 'flex-direction': 'column', 'align-items': 'center'}}, html.p('Height in meters '), html.input( { 'type': 'text', 'placeholder': 'enter height in meters', 'on_change': lambda event:set_height(event['target']['value']) } ), html.p('Weight in kg '), html.input( { 'type': 'text', 'placeholder': 'enter weight in kg', 'on_change': lambda event:set_weight(event['target']['value']) } ), html.p(), html.button({'on_click': get_bmi}, 'Calculate BMI'), html.h3(f'BMI: {round(bmi, 2)}') ) app = FastAPI() configure(app, BMI)
Run the application.
uvicorn bmi:app
This is how it would appear.
Please take a look at the reference section regarding hooks and bmi calculation.
D. Summary
Creating components as user interfaces begins after understanding the structure of HTML elements. Some example applications are presented to see how ReactPy components are created including the use of use_state() hook. We also see how to import a component from other module.