0

I am converting a project from the old React.createComponent to new the ES6 class definition. I have the following component:

class AnswerFrame extends React.Component {
    constructor(props) {
        super(props);
    }
    render() {
        var props = this.props;
        var selectedNumbers = props.selectedNumbers.map(function (i) {
            return (
                <span onClick={props.unselectNumber.bind(null, i)}>
                    {i}
                </span>
            )
        });

        return (
            <div id="answer-frame">
                <div className="well">
                    {selectedNumbers}
                </div>
            </div>
        );
    }
};

The idea is to define an array, selectedNumbers which is an array of spans that each have an onclick event. These are then rendered.

This code worked fine before converting to ES6 but now is giving me the following error:

Error: Objects are not valid as a React child 
(found: object with keys {dispatchConfig, _targetInst, nativeEvent, type, target, currentTarget, eventPhase, bubbles, cancelable, timeStamp, defaultPrevented, isTrusted, view, detail, screenX, screenY, clientX, clientY, ctrlKey, shiftKey, altKey, metaKey, getModifierState, button, buttons, relatedTarget, pageX, pageY, isDefaultPrevented, isPropagationStopped, _dispatchListeners, _dispatchInstances}).
If you meant to render a collection of children, use an array instead or wrap the object using createFragment(object) from the React add-ons. Check the render method of `AnswerFrame`.

Why is this not working anymore?

8
  • what that array contains, its an array of number/string or array of objects ? can you show the result of console.log(this.props.selectedNumbers) ? Commented Apr 26, 2017 at 15:35
  • I think this message is about the contents of this.props.selectedNumbers. Are you sure there are numbers? Commented Apr 26, 2017 at 15:35
  • Maybe the lack of the key property in your span elements causes this problem? Commented Apr 26, 2017 at 15:37
  • yes selectedNumbers is not an array of numbers which it should be Commented Apr 26, 2017 at 15:38
  • If it helps it looks like selectedNumbers is an array of event objects, so I suspect the problem is where you're populating selectedNumbers. You're probably passing an event to something that is expecting event.target.value? Commented Apr 26, 2017 at 15:43

3 Answers 3

1

Yep turns out the problem was in props.selectedNumbers. Trying to figure out the change in the way this is bound when you use ES6, I removed a null from a bind somewhere else in the code.

This:

numbers.push(
    <div className={className} onClick={selectNumber.bind(i)}>
        {i}
    </div>
);

should've been

numbers.push(
    <div className={className} onClick={selectNumber.bind(null,i)}>
        {i}
    </div>
);

So props.selectedNumbers was the object causing the problem.

Sign up to request clarification or add additional context in comments.

1 Comment

I dont know what that does tbh but this solved a random big error of mine, thanks
0

Binding in react props is bad practice (https://daveceddia.com/avoid-bind-when-passing-props/), consider making selectNumber a higher order function:

const selectNumber = (i) => () => {
    // your original function code here
    doWhateverWith(i);
}

And setting onClick to:

<div className={className} onClick={selectNumber(i)}>

4 Comments

Using that approach, how would you go about re-using that function in different classes? Currently I'm defining selectNumber in a parent component and passing it to its children.
@AlexLogan To selectNumber in one action, you can either call it like this in your child functions: selectNumber(i)() or pass it down as (i) => selectNumber(i)()
What might be more coherent though is defining selectNumber as you originally did, but in this case, defining a clickHandler function as (i) => () => selectNumber(i) and doing onClick={ clickHandler(i) }
Whoops, didn't notice that, my bad. Most of my comment is till correct though ;) (will remove)
0

I know that this is just another way of doing the same thing but...

members.push(
    <div className={className} onClick={() => {selectedNumber(i);}}>
       {i}
    </div>
);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.