1

I am using react and redux but I'm getting the following Exception:

foo.js:10 Uncaught Error: findComponentRoot(..., .0.$data.0.0.$22): Unable to find element. This probably means the DOM was unexpectedly mutated (e.g., by the browser), usually due to forgetting a when using tables, nesting tags like <form>, <p>, or <a>, or using non-SVG elements in an parent. Try inspecting the child nodes of the element with React ID

when I press on the button below:

let mapStateToProps = (state) => {
    const user = state.user.get("user");
    return {
        data: state.data.get("data"),
        loading: state.pausedAlarms.get("loading"),
        userId: user&&user.id
    }
};

let mapActionsToProps = (dispatch) => {
    return {
        getData() {
            dispatch(getData());
        },
        selectUser(user){
            dispatch(selectUser(user));
        },
    };
};

let Foo = React.createClass({
    componentWillMount() {
        this.props["getData"]();
    },
    shouldComponentUpdate(nextProps, nextState) {

        if(nextProps["userId"] !== this.props["userId"]) {
            nextProps["getData"]();
        }
        return true;
    },
    render() {
        const {
            data,
            selectUser,
            loading
        } = this.props;

        if (loading) {
            return (
                <div id="3" key="3">LOADING</div>
            );
        }
        else if (data){
            return (
                <div id="1" key="1">

                    <div id="11" key="11">
                        HEADER
                    </div>

                    <button
                        id="2"
                        key="22"
                        onClick={
                            e => {
                                selectUser(new User({id:1,name:"Foo"}))
                            }
                        }
                    >Click</button>
                </div>
            );
        }
        else{
            return null;
        }
    }
});

Pressing the button dispatches the action selectUser, which updates my redux state with a new value for userId. This causes shouldComponentUpdate to call nextProps["getData"]();. The action getData begins by dispatching such that loading is set to true in the reducer.

The code above renders as expected its just that I'm seeing an exception in the console window.

If I do the following instead:

shouldComponentUpdate(nextProps, nextState) {

        if(nextProps["userId"] !== this.props["userId"]) {
            nextProps["getData"]();
            return false;
        }
        return true;
    },

my code works as expected but without the exception. What am I doing wrong? How might I debug this problem?

diedu
  • 19,277
  • 4
  • 32
  • 49
Baz
  • 12,713
  • 38
  • 145
  • 268

1 Answers1

1

I guess the problem is caused that you are dispatching an action in shouldComponentUpdate.

You can dispatch it in componentWillReceiveProps:

componentWillReceiveProps(nextProps) {
    if(nextProps["userId"] !== this.props["userId"]) {
        nextProps["getData"]();
    }
}

shouldComponentUpdate is intended to determine whether a component should be updated, instead of updating the state. Take a look at the following SO discussion:

Is it OK to call setState from within shouldComponentUpdate?


Update 1

Check if the problem is caused by the render structure. Try to simplify it (remove keys, mouniting/unmounting nodes and so on):

getData() {
    return (
        <div>
            HEADER
            <button onClick={ e => { selectUser(new User({id:1,name:"Foo"})) } }>Click</button>
        </div>
    );
}

render() {
    const {
        data,
        selectUser,
        loading
    } = this.props;

    return (
        <div>
            { loading ? 'LOADING' : null }
            { (! loading) && data ? this.getData() : null }
        </div>
    );
}
Community
  • 1
  • 1
Jordan Enev
  • 16,904
  • 3
  • 42
  • 67
  • I know this answer makes perfect sense on the usage of `componentWillReceiveProps` and `shouldComponentUpdate`. But I would like to know whether this really solves the OP. – yadhu Nov 25 '16 at 14:59
  • @Baz check if the problem is caused by the render structure. Check my answer for details. – Jordan Enev Dec 01 '16 at 11:49