diff --git a/.circleci/config.yml b/.circleci/config.yml
index 89932cb..f22d1d7 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -39,14 +39,16 @@ jobs:
name: Install dependencies (dash)
command: |
git clone git@github.com:plotly/dash.git
- git clone --branch fix-prop-types git@github.com:plotly/dash-core-components.git
+ git clone git@github.com:plotly/dash-core-components.git
git clone git@github.com:plotly/dash-html-components.git
git clone git@github.com:plotly/dash-table.git
+ git clone git@github.com:plotly/dash-renderer-test-components
. venv/bin/activate
pip install -e ./dash --quiet
cd dash-core-components && npm install --ignore-scripts && npm run build && pip install -e . && cd ..
cd dash-html-components && npm install --ignore-scripts && npm run build && pip install -e . && cd ..
cd dash-table && npm install --ignore-scripts && npm run build && pip install -e . && cd ..
+ cd dash-renderer-test-components && npm install --ignore-scripts && npm run build:all && pip install -e . && cd ..
- run:
name: Build
diff --git a/src/APIController.react.js b/src/APIController.react.js
index 165044a..ceb4d87 100644
--- a/src/APIController.react.js
+++ b/src/APIController.react.js
@@ -119,11 +119,19 @@ class UnconnectedContainer extends Component {
) {
return (
-
+
);
} else if (appLifecycle === getAppState('HYDRATED')) {
- return ;
+ return (
+
+ );
}
return
{'Loading...'}
;
diff --git a/src/TreeContainer.js b/src/TreeContainer.js
index 900a761..7f6e44a 100644
--- a/src/TreeContainer.js
+++ b/src/TreeContainer.js
@@ -4,7 +4,9 @@ import Registry from './registry';
import {propTypeErrorHandler} from './exceptions';
import {connect} from 'react-redux';
import {
+ addIndex,
any,
+ concat,
contains,
filter,
forEach,
@@ -50,11 +52,12 @@ function validateComponent(componentDefinition) {
}
}
-const createContainer = component => isSimpleComponent(component) ?
+const createContainer = (component, path) => isSimpleComponent(component) ?
component :
();
function CheckedComponent(p) {
@@ -87,14 +90,16 @@ CheckedComponent.propTypes = {
id: PropTypes.string,
};
class TreeContainer extends Component {
- getChildren(components) {
+ getChildren(components, path) {
if (isNil(components)) {
return null;
}
return Array.isArray(components) ?
- map(createContainer, components) :
- createContainer(components);
+ addIndex(map)(
+ (component, i) => createContainer(component, concat(path, ['props', 'children', i])),
+ components
+ ) : createContainer(components, concat(path, ['props', 'children']));
}
getComponent(_dashprivate_layout, children, loading_state, setProps) {
@@ -148,7 +153,7 @@ class TreeContainer extends Component {
const {
_dashprivate_dependencies,
_dashprivate_dispatch,
- _dashprivate_paths
+ _dashprivate_path
} = this.props;
const id = this.getLayoutProps().id;
@@ -165,8 +170,7 @@ class TreeContainer extends Component {
// Always update this component's props
_dashprivate_dispatch(updateProps({
props: newProps,
- id: id,
- itempath: _dashprivate_paths[id]
+ itempath: _dashprivate_path
}));
// Only dispatch changes to Dash if a watched prop changed
@@ -194,12 +198,13 @@ class TreeContainer extends Component {
const {
_dashprivate_dispatch,
_dashprivate_layout,
- _dashprivate_loadingState
+ _dashprivate_loadingState,
+ _dashprivate_path
} = this.props;
const layoutProps = this.getLayoutProps();
- const children = this.getChildren(layoutProps.children);
+ const children = this.getChildren(layoutProps.children, _dashprivate_path);
const setProps = this.getSetProps(_dashprivate_dispatch);
return this.getComponent(_dashprivate_layout, children, _dashprivate_loadingState, setProps);
@@ -211,9 +216,9 @@ TreeContainer.propTypes = {
_dashprivate_dispatch: PropTypes.func,
_dashprivate_layout: PropTypes.object,
_dashprivate_loadingState: PropTypes.object,
- _dashprivate_paths: PropTypes.any,
_dashprivate_requestQueue: PropTypes.any,
_dashprivate_config: PropTypes.object,
+ _dashprivate_path: PropTypes.array,
};
function isLoadingComponent(layout) {
@@ -286,7 +291,6 @@ function getLoadingState(layout, requestQueue) {
export const AugmentedTreeContainer = connect(
state => ({
dependencies: state.dependenciesRequest.content,
- paths: state.paths,
requestQueue: state.requestQueue,
config: state.config
}),
@@ -295,8 +299,8 @@ export const AugmentedTreeContainer = connect(
_dashprivate_dependencies: stateProps.dependencies,
_dashprivate_dispatch: dispatchProps.dispatch,
_dashprivate_layout: ownProps._dashprivate_layout,
+ _dashprivate_path: ownProps._dashprivate_path,
_dashprivate_loadingState: getLoadingState(ownProps._dashprivate_layout, stateProps.requestQueue),
- _dashprivate_paths: stateProps.paths,
_dashprivate_requestQueue: stateProps.requestQueue,
_dashprivate_config: stateProps.config,
})
diff --git a/tests/test_render.py b/tests/test_render.py
index 308308b..8b51f5f 100644
--- a/tests/test_render.py
+++ b/tests/test_render.py
@@ -8,6 +8,7 @@
from dash.development.base_component import Component
import dash_html_components as html
import dash_core_components as dcc
+import dash_renderer_test_components
from bs4 import BeautifulSoup
from selenium.webdriver.common.action_chains import ActionChains
@@ -2960,3 +2961,32 @@ def display_content(pathname):
test_cases[test_case_id]['name']
)
)
+
+ def test_set_props_behavior(self):
+ app = dash.Dash(__name__)
+ app.layout = html.Div([
+ dash_renderer_test_components.UncontrolledInput(
+ id='id',
+ value=''
+ ),
+ html.Div(
+ id='container',
+ children=dash_renderer_test_components.UncontrolledInput(
+ value=''
+ ),
+ )
+ ])
+
+ self.startServer(
+ app,
+ debug=True,
+ use_reloader=False,
+ use_debugger=True,
+ dev_tools_hot_reload=False,
+ )
+
+ self.wait_for_element_by_css_selector('#id').send_keys('hello input with ID')
+ self.wait_for_text_to_equal('#id', 'hello input with ID')
+
+ self.wait_for_element_by_css_selector('#container input').send_keys('hello input without ID')
+ self.wait_for_text_to_equal('#container input', 'hello input without ID')