prog
prog

Reputation: 150

Working around the <td> limitation in React.js

renderTaskSection() {
    const { task, priority, isCompleted } = this.props;

    const taskStyle = {
        color: isCompleted ? 'green' : 'red',
        cursor: 'pointer'
    };

    if (this.state.isEditing) {
        return (
            <td>
                <form onSubmit={this.onSaveClick.bind(this)}>
                    <input type="text" defaultValue={task} ref="editInput" />
                    <input type="text" defaultValue={priority} ref="editInput2" />
                </form>
            </td>
        );
    }

    return (
        <div>
        <td style={taskStyle}
            onClick={this.props.toggleTask.bind(this, task)}
        >
            {task}
        </td>
        <td style={taskStyle}
            onClick={this.props.toggleTask.bind(this, task)}
        >
            {priority}
        </td>
        </div>
    );
}

I have this line of code and it seems that whenever I add a td for each element, it causes some kind of issues, if I have one td element instead of two, everything is fine.

I thought wrapping the elements in a div would fix everything, but I was wrong, so I am not sure why this causes a lot of problem with React, especially since we can add two components one after another in a single render. Is there an easy workaround for this?

These are some of the messages I get on Firefox:

Warning: validateDOMNesting(...): <div> cannot appear as a child of <tr>. See TodosListItem > tr > div.  bundle.js:11406:10
Warning: validateDOMNesting(...): <td> cannot appear as a child of <div>. See TodosListItem > div > td.  bundle.js:11406:10
Error: findComponentRoot(..., .0.2.1.$1.0.0): Unable to find element. This probably means the DOM was unexpectedly mutated (e.g., by the browser), usually due to forgetting a <tbody> when using tables, nesting tags like <form>, <p>, or <a>, or using non-SVG elements in an <svg> parent. Try inspecting the child nodes of the element with React ID ``.  bundle.js:10062:16
[WDS] Disconnected!  bundle.js:635:11
saveTask  bundle.js:28539:14
Error: findComponentRoot(..., .0.2.1.$0.0.0): Unable to find element. This probably means the DOM was unexpectedly mutated (e.g., by the browser), usually due to forgetting a <tbody> when using tables, nesting tags like <form>, <p>, or <a>, or using non-SVG elements in an <svg> parent. Try inspecting the child nodes of the element with React ID ``.  bundle.js:10062:16
TypeError: onClickListeners[id] is undefined[Learn More]

Also, I get a similar error when I enclose two inputs enclosed within their own td tags with the form tag.

Upvotes: 0

Views: 475

Answers (1)

Jo Peyper
Jo Peyper

Reputation: 390

Change this renderTaskSection to return the <tr> and the calling render to have a <tbody> only

render() {
    <table>
        <tbody>
            {this.renderTaskSection()}
        </tbody>
    </table>
}

renderTaskSection() {
    const { task, priority, isCompleted } = this.props;

    const taskStyle = {
        color: isCompleted ? 'green' : 'red',
        cursor: 'pointer'
    };

    if (this.state.isEditing) {
        return (
            <tr>
                <td>
                    <form onSubmit={this.onSaveClick.bind(this)}>
                        <input type="text" defaultValue={task} ref="editInput" />
                        <input type="text" defaultValue={priority} ref="editInput2" />
                    </form>
                </td>
            </tr>
        );
    }

    return (
        <tr>
            <td style={taskStyle} onClick={this.props.toggleTask.bind(this, task)}>
                {task}
            </td>
            <td style={taskStyle} onClick={this.props.toggleTask.bind(this, task)}>
                {priority}
            </td>
        </tr>
    );
}

Upvotes: 1

Related Questions