Converting React.js components to Dash compatible components

Is there any kind of components that cant be converting into Dash components. For example, what about components that use JSX and any additional functions that are used to create the component in React? What are things to be mindful of when making these conversions?

Thanks.

1 Like

@jbrown15 - To start, see https://plot.ly/dash/plugins.

The main restriction to keep in mind is that the props of the React components need to be JSON serializable. The props of the React component end up being the keyword arguments of the python Dash components. That means functions are not allowed as props.

The dash_core_components source code is here: https://github.com/plotly/dash-core-components. A lot of the code behind components is very simple - I recommend checking out the source code to gain a better idea of how this works.

If you encounter any issues or if you have any questions about converting an existing React component to Dash, feel free to post in this forum!

Thanks Chris! @chriddyp Is it possible I can see an example of the javascript prior to the Dash compatible change. This way I can have a better idea of the methodology. I am completely new to React.js so there is a disconnect for me on how the props are being adapted prior to the change.

Thanks if this is at all possible.

Yup! At a high-level, here’s how components work:

  • There is a separate library called dash-rendrerer (https://github.com/plotly/dash-renderer). This library renders the components that are supplied.
  • dash-rendrerer passes in the properties into the react components. If any of the component’s attributes / properties change, then the component can tell dash-renderer about that change by calling updateProps({propertyNameThatChanged: newValue}). dash-rendrerer will then rerender the component with the new property that you specified in updateProps.

Here’s how that works in the dcc.Input component: https://github.com/plotly/dash-core-components/blob/fae273456ba74fa095c8d0b68aac5b921a64a6b9/src/components/Input.react.js#L42

You can remove those setProps and fireEvent lines and you’d have a standalone, stateful Input component.

Finally, I also recommend checking out our React tutorial here: https://academy.plot.ly :slight_smile:

1 Like

Hi,
I’ve been following the tutorials to create new Dash components from React. Now I’m coming back to this

as I’m having issues rendering even simple React components in Dash.

For example, I was trying to build a simple Dash component that creates a nice header, such as the one used in the react tutorial (React plotly.js in JavaScript), but I don’t seem to be able to get neither an external logo.svg nor the CSS information transferred into my Dash component.
After running npm run prepublish everything seems fine, but when calling python usage.py, I only get the standard header and no logo, for example.

So, how could I integrate “external” files, in particular CSS into a custom-built component? (Sorry if this doesn’t make sense, but I’m new to all this…)

A similar issue happens when trying to integrate this slider: GitHub - whoisandy/react-rangeslider: A lightweight responsive react range slider component.A fast & lightweight react component as a drop in replacement for HTML5 input range slider element.
Everything seems to work fine, but I get an error (will post later) when including import 'react-rangeslider/lib/index.css' in the react.js file. So again CSS may be a problem?

If I don’t include this line, everything runs well, but the slider is not actually visible (even though somehow present when checking site elements with inspect). If needed, I can post a code example later.

Any help would be much appreciated!
Thanks

EDIT:
Example of what I was trying to do with the header, ExampleComponent.react.js:

import React, {Component} from 'react';
import PropTypes from 'prop-types';

import './App.css';
import logo from './logo.svg';

export default class ExampleComponent extends Component {

  render() {
        const {logo} = this.props;

        return (

            <div className="App">
                <header className="App-header">
                    <img src={logo} className="App-logo" alt="logo" />
                    <h1 className="App-title">Plotly and React Example App</h1>
                </header>
           </div>
    );
  }
 }

App.css (defining App-header etc.) and logo.svg are in the same folder as ExampleComponent.react.js. Running npm run prepublish yields:

13:8  error  Parse errors in imported module './App.css': Unexpected token . (1:1)  import/no-deprecated
  14:8  error  No default export found in module                                      import/default

âś– 2 problems (2 errors, 0 warnings)

[builder:proc:end:1] Command: eslint --fix --ignore-path .gitignore .
[builder:builder-core:end:30338] Task: run lint, Error: Command failed: sh -c eslint --fix --ignore-path .gitignore .

[builder:proc:end:1] Command: builder run lint && builder run test-frontend-cov
[builder:builder-core:end:30331] Task: run check, Error: Command failed: sh -c builder run lint && builder run test-frontend-cov

npm ERR! Test failed.  See above for more details.
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! jan-components@0.0.1 prepublish: `npm test && builder run build-dist && npm run copy-lib`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the jan-components@0.0.1 prepublish script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

I also tried with import 'App.css'; import logo from 'logo.svg'; which yields

  13:1   error  'App.css' should be listed in the project's dependencies. Run 'npm i -S App.css' to add it    import/no-extraneous-dependencies
  13:8   error  Unable to resolve path to module 'App.css'                                                    import/no-unresolved
  13:8   error  Unexpected use of file extension "css" for "App.css"                                          import/extensions
  14:1   error  'logo.svg' should be listed in the project's dependencies. Run 'npm i -S logo.svg' to add it  import/no-extraneous-dependencies
  14:18  error  Unable to resolve path to module 'logo.svg'                                                   import/no-unresolved
  14:18  error  Unexpected use of file extension "svg" for "logo.svg"                                         import/extensions

âś– 6 problems (6 errors, 0 warnings)

and the suggestion npm i -S App.css does not work either.

Similarly, I tried to install the slider from the link above using npm install react-rangeslider --save and importing it with

import Slider from 'react-rangeslider';
import 'react-rangeslider/lib/index.css';

The first command works, the second causes issues:

[builder:proc:start] Command: karma start node_modules/dash-components-archetype/config/karma/karma.conf.coverage.js

WARNING in ./~/plotly.js/dist/plotly.js
Critical dependencies:
7:479-486 This seems to be a pre-built javascript file. Though this is possible, it's not recommended. Try to require the original source to get better results.
 @ ./~/plotly.js/dist/plotly.js 7:479-486

ERROR in ./~/react-rangeslider/lib/index.css
Module parse failed: ~/Plotly/DashComponentTrials/jan-components/node_modules/react-rangeslider/lib/index.css Unexpected token (4:0)
You may need an appropriate loader to handle this file type.
SyntaxError: Unexpected token (4:0)
    at Parser.pp$4.raise (~/Plotly/DashComponentTrials/jan-components/node_modules/acorn/dist/acorn.js:2221:15)
    at Parser.pp.unexpected (~/Plotly/DashComponentTrials/jan-components/node_modules/acorn/dist/acorn.js:603:10)
    at Parser.pp$3.parseExprAtom (~/Plotly/DashComponentTrials/jan-components/node_modules/acorn/dist/acorn.js:1822:12)
    at Parser.pp$3.parseExprSubscripts (~/Plotly/DashComponentTrials/jan-components/node_modules/acorn/dist/acorn.js:1715:21)
    at Parser.pp$3.parseMaybeUnary (~/Plotly/DashComponentTrials/jan-components/node_modules/acorn/dist/acorn.js:1692:19)
    at Parser.pp$3.parseExprOps (~/Plotly/DashComponentTrials/jan-components/node_modules/acorn/dist/acorn.js:1637:21)
    at Parser.pp$3.parseMaybeConditional (~/Plotly/DashComponentTrials/jan-components/node_modules/acorn/dist/acorn.js:1620:21)
    at Parser.pp$3.parseMaybeAssign (~/Plotly/DashComponentTrials/jan-components/node_modules/acorn/dist/acorn.js:1597:21)
    at Parser.pp$3.parseExpression (~/Plotly/DashComponentTrials/jan-components/node_modules/acorn/dist/acorn.js:1573:21)
    at Parser.pp$1.parseStatement (~/Plotly/DashComponentTrials/jan-components/node_modules/acorn/dist/acorn.js:727:47)
    at Parser.pp$1.parseTopLevel (~/Plotly/DashComponentTrials/jan-components/node_modules/acorn/dist/acorn.js:638:25)
    at Parser.parse (~/Plotly/DashComponentTrials/jan-components/node_modules/acorn/dist/acorn.js:516:17)
    at Object.parse (~/Plotly/DashComponentTrials/jan-components/node_modules/acorn/dist/acorn.js:3098:39)
    at Parser.parse (~/Plotly/DashComponentTrials/jan-components/node_modules/webpack/lib/Parser.js:902:15)
    at NormalModule.<anonymous> (~/Plotly/DashComponentTrials/jan-components/node_modules/webpack/lib/NormalModule.js:104:16)
    at NormalModule.onModuleBuild (~/Plotly/DashComponentTrials/jan-components/node_modules/webpack-core/lib/NormalModuleMixin.js:310:10)
 @ ./src/components/ExampleComponent.react.js 34:745-787
15 02 2018 09:14:11.383:INFO [karma]: Karma v1.7.1 server started at http://0.0.0.0:9999/
15 02 2018 09:14:11.387:INFO [launcher]: Launching browser PhantomJS with unlimited concurrency
15 02 2018 09:14:11.394:INFO [launcher]: Starting browser PhantomJS
15 02 2018 09:14:12.048:INFO [PhantomJS 2.1.1 (Linux 0.0.0)]: Connected on socket GACkXD8mtJOCwNykAAAA with id 62302454
PhantomJS 2.1.1 (Linux 0.0.0) ERROR
  Error: Cannot find module "react-rangeslider/lib/index.css"
  at webpack:///src/components/ExampleComponent.react.js:9:1611 <- ~/Plotly/DashComponentTrials/jan-components/test/main.js:48733

PhantomJS 2.1.1 (Linux 0.0.0): Executed 0 of 0 ERROR (1.304 secs / 0 secs)

[builder:proc:end:1] Command: karma start node_modules/dash-components-archetype/config/karma/karma.conf.coverage.js
[builder:builder-core:end:30530] Task: run test-frontend-cov, Error: Command failed: sh -c karma start node_modules/dash-components-archetype/config/karma/karma.conf.coverage.js

[builder:proc:end:1] Command: builder run lint && builder run test-frontend-cov
[builder:builder-core:end:30509] Task: run check, Error: Command failed: sh -c builder run lint && builder run test-frontend-cov

npm ERR! Test failed.  See above for more details.
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! jan-components@0.0.1 prepublish: `npm test && builder run build-dist && npm run copy-lib`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the jan-components@0.0.1 prepublish script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.