Dynamic Children Injection and Redux Binding

Viewed 483

We are trying to inject dynamic children into a react app that is using React-Redux and Redux, and are experiencing an issue with the binding on the children props. I've distilled the problem into the following example code (JSFiddle). The issue is that the original rendered element updates just fine, but the dynamically injected portion does not. The strange thing is that the update is picked up in the redux store, and is fed to the props correctly.

const initialState = {
  renderProperty: "Red Fish",
  getChildrenProperty: "Blue Fish",
}

function MainReducer(state = initialState, action) {
switch (action.type) {
        case 'PROBLEM_CHILD_INSIDE_RENDER':
            return Object.assign({}, state, {
        renderProperty: action.mutatedProperty
      })
      case 'PROBLEM_CHILD_INSIDE_GET_CHILDREN':
            return Object.assign({}, state, {
        getChildrenProperty: action.mutatedProperty
      })
    default:
      return state
    }
}

const store = Redux.createStore(MainReducer);

function mapStateToProps(state) {
    return {
        renderProperty     : state.renderProperty,
        getChildrenProperty : state.getChildrenProperty
    }
}
function mapDispatchToProps(dispatch) {
    return {
        actions: Redux.bindActionCreators(actionCreators, dispatch)
    };
}


class ProblemChild extends React.Component {
constructor() {
        super();
        this.childrenInjected = false;
        this.state = {children: null};
    }
    /**
     * Add children in setDynamicChildren() versus within render()
     */
    componentDidMount() {
        this.setDynamicChildren();
    }
    setDynamicChildren() {
        this.setState({
            children: this.getChildren()
        });
    }
    getChildren() {
        var me = this;
        console.log(this);
        return (
            <div>
                <br/>
                <button style={{marginBottom: '10px'}}
                        onClick={me._handleGetChildrenAction.bind(me)} >UI State Change Action for prop in getChildren()</button>
                <br/>
                <span>prop in getChildren(): <b>{me.props.getChildrenProperty}</b></span>
            </div>
        )
    }
    render() {
        var me = this,
            childrenInjected = me.childrenInjected;
    console.log(this.props);
        if(me.state.children && !me.childrenInjected) {
            return (
                <div >
                    <button style={{marginBottom: '10px'}}
                            onClick={me._handleRenderAction.bind(me)} > UI State Change Action for prop in render()</button>
                    <br/>
                    <span>prop in render(): <b>{me.props.renderProperty}</b></span>
                    <br/>
                    {this.state.children} <br/>
                </div>
            )
        }
        else {
            return (
                <div>placeholder, yo</div>
            )
        }
    }
  _handleRenderAction() {
        var me = this;
        store.dispatch(actionForPropInsideRender('One Fish!'));
    }
    _handleGetChildrenAction() {
        var me = this;
        store.dispatch(actionForPropInsideGetChildren('Two Fish!'));
    }
}
ProblemChild = ReactRedux.connect(mapStateToProps,mapDispatchToProps)(ProblemChild);

function actionForPropInsideRender(mutatedProperty) {
    return {
        type: 'PROBLEM_CHILD_INSIDE_RENDER',
        mutatedProperty
    }
}
function actionForPropInsideGetChildren(mutatedProperty) {
    return {
        type: 'PROBLEM_CHILD_INSIDE_GET_CHILDREN',
        mutatedProperty
    }
}

const actionCreators = {actionCreatorForPropInsideRender, actionCreatorForPropInsideGetChildren};

function actionCreatorForPropInsideRender(state, mutatedProperty) {
    let newState = state.setIn(['uiState', 'renderProperty'], mutatedProperty),
        nodeValue;

    nodeValue = newState.getIn(['uiState', 'renderProperty']);
    return newState;
}

function actionCreatorForPropInsideGetChildren(state, mutatedProperty) {
    let newState = state.setIn(['uiState', 'getChildrenProperty'], mutatedProperty),
        nodeValue;

    nodeValue = newState.getIn(['uiState', 'getChildrenProperty']);
    return newState;
}

ReactDOM.render(
    <div>
        <ReactRedux.Provider store={store}>
            <ProblemChild />
        </ReactRedux.Provider>
    </div>,
    document.getElementById('container')
);
1 Answers
Related