A "React for a Python Developer" guide
See original GitHub issueI think that we should do whatever we can to reduce the barriers of entry in creating custom Dash components. One of the largest barriers to entry is React and JavaScript itself: our community is (by definition) mostly Python developers.
One way that we can help out our community in creating or customizing Dash components is by providing a really friendly, step-by-step guide to creating a Dash component. I’ll call this the “React.js for the Python Developer Guide”.
Below is a rough outline of what I’m imagining. Would love feedback on this!
For Tutorial 1, here’s a rough syllabus that I’ve used in the workshops:
-
Introduction:
- React and JavaScript is easier than it seems, you can do it!
- Most Dash component’s are simple wrappers around existing components. And there are hundreds of thousands of them.
-
Developer Setup
- Installing Node, NPM, and
create-react-app- In practice, it would be nice to use our
dash-component-archetypehere once we make it better
- In practice, it would be nice to use our
- Installing Node, NPM, and
-
Making your first change
- Opening up
App.jsand changing “React” to “Dash” - Observing the hot-reload
- Making an error and seeing where to find error messages:
throw error - Doing
console.logand seeing the data
- Opening up
-
Quick React vs Python:
- React has classes’s like Python classes
- Declare variables in JavaScript:
constandlet - JavaScript “objects” are Python’s “dict”
- Except the keys are always strings
console.loginstead ofprintimportandexport
-
Quick create your own component in the same file as
App.js:- Create
Headerand include it inApp:
class Header extends Component { render() { return 'Header' } } class App extends Component { ... render() { ... return <Header/> } }- Thread a property through:
return <div>{this.props.name}</div>const myHeaderName = 'Dash Header' return <Header name={myHeaderName}/>- Add another property like style:
return <div style={this.props.style}>{this.props.name}</div>const myHeaderName = 'Dash Header'; const style={'color': 'blue', 'fontSize': 20} return <Header name={myHeaderName}/> - Create
-
Making this component Dash-ready:
- Quick pause: this “component” is hydrated from JavaScript, now let’s make it a standalone Dash component
- Move it to a new file
- Add
propTypes - Run the toolchain
- Fire up
usage.pyand have:
app.layout = html.Div([ my_component.Header(name='Dash Header', style={'color': 'blue', 'fontSize': 20}) ]) - Isn't that amazing? Dash components are 1-1 with their React components -
Making it more complex with updates and events in react:
- Making an
Inputcomponent
class TextInput extends Component { render() { return ( <input value={this.props.value}/> ) } }class App extends Component { render() { const myValue = 'Text input' return <TextInput value={myValue}/> } }- Inputs are “controlled”:
- Note how you can’t enter any text in that input. It’s
valueis fixed. - Note how if you remove
value={...}, then you could type into it - So, we need a way to handle keypresses and feed those values back into the input
- Note how you can’t enter any text in that input. It’s
- Adding an onChange:
<input value={this.props.value} onChange={(e) => { console.log(e.target.value) }}/>- Woah, that
(e) => {...}thing? That’s basically like a Pythonlambdafunction. Inline, anonymous function. e.target.value? That’s just “something you know”, it’s the standard syntax for input events with JavaScript
- Woah, that
- Start typing and check out your console. Letters!
- Adding state:
class TextInput extends Component { constructor() { this.state = { value: 'test' } } render() { return ( <input value={this.state.value}/> ) } }this.stateis a special react class property. We refer to it withthis, just like as in python classes- React provides a special way to update
this.state:this.setState. When you callthis.setState, it will call therendercomponent automatically to “rerender” your component. Let’s try it:
class TextInput extends Component { constructor() { this.state = { value: 'test' } } render() { console.log('rendering') return ( <input value={this.props.value} onChange={e => { console.log(e.target.value); this.setState({value: e.target.value}); }} /> ) } }- Now type: notice how we’re just renderering and rendering our component. And notice how our input is now getting updated!
- Now, let’s move the state from
TextInputtoApp:
class App extends Component { constructor() { this.state = { value: 'test' } } render () { console.log('rendering App') return ( <div> <TextInput value={this.state.value} updateValue={newValue => this.setState({value: newValue})} /> </div> ); } } class TextInput extends Component { render() { console.log('rendering TextInput') return ( <input value={this.props.value} onChange={e => { console.log(e.target.value); this.props.updateValue(e.target.value) }} /> ) } }- data is flowing in a big loop! From the input up to the app, re-rendering the app and re-rendering the
TextInputwith the new value.
- Making an
-
Now here’s the kicker.
App? That’s basicallydash-renderer. It’s rendering all of the components and it’s providing the data down into the components as props. It also provides anupdateValue-like prop, except it’s calledsetPropsand it takes an object. So, to make this Dash-ready, let’s:- Move
TextInputinto it’s own file - Add
propTypes - Rename
updateValuetosetPropsand update the call signature tosetProps({value: e.target.value}) - Run the toolchain
- Add it to
usage.pyand create a callbackvalueis now a property that we “listen” to as acallbackInput
- Move
-
Now, in practice we won’t create our own components. We’ll frequently just provide wrappers around existing components. Let’s try it out with the react colorpicker:
npm install react-colorpickernpmis thepipfor node
import ColorPicker from 'react-colorpicker'- Add
this.setProps - Add propetypes
- Run the toolchain
- Magic
-
Advanced:
- If the component’s properties don’t update with callbacks, then it can manage its own state completely. This will be a quite a bit faster as the dash-renderer re-render cycle can take a moment or two.
- You can check if a component can manage its own state by seeing if
this.props.setPropsis defined or not. - For an example, see the
Inputcomponent indash-core-componentssource
- You can check if a component can manage its own state by seeing if
- We use Ramda as our “standard library”, here’s the docs: https://ramdajs.com/
- Read the source for the existing components in
dash-core-components - Subscribe to this issue to be aware of breaking changes in the components: https://github.com/plotly/dash-components-archetype/issues/40
- If the component’s properties don’t update with callbacks, then it can manage its own state completely. This will be a quite a bit faster as the dash-renderer re-render cycle can take a moment or two.
Issue Analytics
- State:
- Created 5 years ago
- Reactions:9
- Comments:17 (12 by maintainers)

Top Related StackOverflow Question
@AmirAlavi - Definitely!
For what its worth, we have a new version that should make this easier: https://github.com/plotly/dash-component-boilerplate. With the new version, you shoulnd’t need to worry about webpack, dev vs normal, hot reloading, etc. You should just be able to follow the new instructions.
For external dependencies, in a nutshell we need a section that explains that:
is the equivalent of
pip installand thatnode_modulesfolder is basically like a virtualenv folder: local installations.Also, an explanation of how
importandexportwork and how it’s slightly different than pythonAs a mostly Python developer, another major issue I’ve run into besides ReactJS is the javascript toolchain that is required for building a custom Dash component. It’s something you can ignore if you aren’t using external libraries, but as soon as you need to add a dependency, things get confusing. I’ve found it so difficult to understand what’s happening with webpack, webpack.config files, bundle.js, “hot loading”, dev vs “normal” configurations, etc.
Honestly, this has personally been my greatest barrier to creating custom dash components, not learning ReactJS (as someone mentioned above, there are many great tutorials on this from Facebook or even codecademy).
Is there any room for this in the tutorial? I’m thinking something different than the wrapper around react-colorpicker from above. That is already a react component, that doesn’t really require external JS libraries/dependencies, and so doesn’t really touch on toolchain issues.