Skip to content

Commit b15ddec

Browse files
committed
Use functional component instead of class-based
1 parent d825287 commit b15ddec

File tree

1 file changed

+42
-59
lines changed

1 file changed

+42
-59
lines changed

Diff for: template/my_component/frontend/src/MyComponent.tsx

+42-59
Original file line numberDiff line numberDiff line change
@@ -1,84 +1,67 @@
11
import {
22
Streamlit,
3-
StreamlitComponentBase,
43
withStreamlitConnection,
4+
ComponentProps,
55
} from "streamlit-component-lib"
6-
import React, { ReactNode } from "react"
7-
8-
interface State {
9-
numClicks: number
10-
isFocused: boolean
11-
}
6+
import React, { useEffect, useState, ReactElement } from "react"
127

138
/**
149
* This is a React-based component template. The `render()` function is called
1510
* automatically when your component should be re-rendered.
1611
*/
17-
class MyComponent extends StreamlitComponentBase<State> {
18-
public state = { numClicks: 0, isFocused: false }
12+
function MyComponent({ args, disabled, theme }: ComponentProps): ReactElement {
13+
const { name } = args
1914

20-
public render = (): ReactNode => {
21-
// Arguments that are passed to the plugin in Python are accessible
22-
// via `this.props.args`. Here, we access the "name" arg.
23-
const name = this.props.args["name"]
15+
const [isFocused, setIsFocused] = useState(false)
16+
const [style, setStyle] = useState<React.CSSProperties>({})
17+
const [numClicks, setNumClicks] = useState(0)
2418

25-
// Streamlit sends us a theme object via props that we can use to ensure
26-
// that our component has visuals that match the active theme in a
27-
// streamlit app.
28-
const { theme } = this.props
29-
const style: React.CSSProperties = {}
19+
useEffect(() => {
20+
if (!theme) return
3021

31-
// Maintain compatibility with older versions of Streamlit that don't send
32-
// a theme object.
33-
if (theme) {
34-
// Use the theme object to style our button border. Alternatively, the
35-
// theme style is defined in CSS vars.
36-
const borderStyling = `1px solid ${
37-
this.state.isFocused ? theme.primaryColor : "gray"
38-
}`
39-
style.border = borderStyling
40-
style.outline = borderStyling
41-
}
22+
// Use the theme object to style our button border. Alternatively, the
23+
// theme style is defined in CSS vars.
24+
const borderStyling = `1px solid ${isFocused ? theme.primaryColor : "gray"}`
25+
setStyle({ border: borderStyling, outline: borderStyling })
26+
}, [theme, isFocused])
4227

43-
// Show a button and some text.
44-
// When the button is clicked, we'll increment our "numClicks" state
45-
// variable, and send its new value back to Streamlit, where it'll
46-
// be available to the Python program.
47-
return (
48-
<span>
49-
Hello, {name}! &nbsp;
50-
<button
51-
style={style}
52-
onClick={this.onClicked}
53-
disabled={this.props.disabled}
54-
onFocus={this._onFocus}
55-
onBlur={this._onBlur}
56-
>
57-
Click Me!
58-
</button>
59-
</span>
60-
)
61-
}
28+
useEffect(() => {
29+
Streamlit.setComponentValue(numClicks)
30+
}, [numClicks])
6231

6332
/** Click handler for our "Click Me!" button. */
64-
private onClicked = (): void => {
65-
// Increment state.numClicks, and pass the new value back to
66-
// Streamlit via `Streamlit.setComponentValue`.
67-
this.setState(
68-
prevState => ({ numClicks: prevState.numClicks + 1 }),
69-
() => Streamlit.setComponentValue(this.state.numClicks)
70-
)
33+
const onClicked = (): void => {
34+
setNumClicks((prevNumClicks) => prevNumClicks + 1)
7135
}
7236

7337
/** Focus handler for our "Click Me!" button. */
74-
private _onFocus = (): void => {
75-
this.setState({ isFocused: true })
38+
const onFocus = (): void => {
39+
setIsFocused(true)
7640
}
7741

7842
/** Blur handler for our "Click Me!" button. */
79-
private _onBlur = (): void => {
80-
this.setState({ isFocused: false })
43+
const onBlur = (): void => {
44+
setIsFocused(false)
8145
}
46+
47+
// Show a button and some text.
48+
// When the button is clicked, we'll increment our "numClicks" state
49+
// variable, and send its new value back to Streamlit, where it'll
50+
// be available to the Python program.
51+
return (
52+
<span>
53+
Hello, {name}! &nbsp;
54+
<button
55+
style={style}
56+
onClick={onClicked}
57+
disabled={disabled}
58+
onFocus={onFocus}
59+
onBlur={onBlur}
60+
>
61+
Click Me!
62+
</button>
63+
</span>
64+
)
8265
}
8366

8467
// "withStreamlitConnection" is a wrapper function. It bootstraps the

0 commit comments

Comments
 (0)