Search code examples
javascriptnode.jsreactjsreact-datepicker

"JavaScript: Uncaught Invariant Violation: Objects are not valid as a React child" - on second of two identical date inputs


I'm getting the above error on the second, of what look like identical (to me) pieces of code! They both use the standard react-datepicker package. First:

<div>
    <label>Date Terminated</label>
    <div>
        <DateControl 
            value={this.state.edit_course.date_terminated || null}
            name="date_terminated_course"
            onChange={(e) => this.handleDetailChangeCourse("date_terminated", e.target.value)}
        />
    </div>
</div>

Second:

<div>
    <label>Date Terminated</label>
    <div>
        <DateControl 
            value={this.state.edit_prereq.date_terminated_prereq || null}
            name="date_terminated_prereq"
            onChange={(e) => this.handleDetailChangePrereqs("date_terminated", e.target.value)}
        />
    </div>
</div>

As soon as the handleDetailChangePrereqs() call is made the error occurs during the render.

The two handle routines look like this:

handleDetailChangeCourse(prop, value) {
    if (prop === "date_terminated") {
        console.log(`date: ${value}`)
        console.log(typeof value)
        console.log(JSON.stringify(value))
    }
    const index = this.state.index
    const courses = this.state.temp_courses
    courses[index][prop] = value
    this.setState({ temp_courses: courses });
}

handleDetailChangePrereqs(prop, value) {
    if (prop === "date_terminated") {
        console.log(`date: ${value}`)
        console.log(typeof value)
        console.log(JSON.stringify(value))
    }
    const index = this.state.prereqIndex
    const prereqs = this.state.temp_prereqs
    prereqs[index][prop] = value
    this.setState(() => ({ temp_prereqs: prereqs }));
}

When I run the code and select/enter a date for the first control handleDetailChangeCourse)() it works fine and outputs the following:

date: 1608069600000
object
"2020-12-15T22:00:00.000Z"

But when I do the same for the second control handleDetailChangePrereqs() it errors after giving me this output:

date1: 1608069600000
object
"2020-12-15T22:00:00.000Z"

I understand the error message, and having read lots of solutions on this site most of them usually final they are rendering an object and not what they thought was a string. I seem to be rendering an object in both cases but the first one works.

Having spent many hours logging out all sort of information I am lost as to what else I can look at. There are other DateControl calls within this same program and they work fine too. It is the second one that also renders an object's .date_terminated property that fails (albeit a separate object in each case).

The DateControl component looks like this:

setDate(selected_date) {
    this.props.onChange({
        target: {
            name: this.props.name,
            value: selected_date
        }
    });
},

render() {
    return (
        <DatePicker
            disabled={this.props.readOnly}
            onBlur={this.props.onBlur}
            style={this.props.style}
            dateFormat="DD/MM/YYYY"
            locale="en-za"
            placeholderText={this.props.readOnly ? "" : "DD/MM/YYYY"}
            selected={this.props.value ? moment(this.props.value): null}
            onChange={(date) => { this.setDate(date) } }
        />
    );
}

Solution

  • Thanks to Shyam and Vishal for suggesting that I created a sandbox. I spent quite a bit of time preparing some code to do just that before seeing where my problem was!

    As I stated in my question: "I understand the error message, and having read lots of solutions on this site most of them usually final they are rendering an object and not what they thought was a string."

    And I was doing just that.

    The problem was not where I had decided it was before asking this question, it was elsewhere:

    <table>
    ...
        <td>
            { item.date_terminated_prereq }
        </td>
    ...
    </table>
    

    As can be seen from the above code segment I was actually displaying the changed date as part of a table. The moment it rendered I got the error message.

    So the learning that has come from this for me, is that everywhere on StackOverflow I have seen mention of this issue it has been because an 'object' was being displayed accidentally, or unknowingly. I should have taken that in good faith and looked for it as a problem in my code, rather than stubbornly think the error was with the <DateControl />.

    Note to reviewer: Should I just delete this whole question as my answer is more philosophical than practical?