Paul Gudu
Paul Gudu

Reputation: 441

Uncaught Error: Element type is invalid: expected a string (for built-in components) or a class/function... after clicking the Add button

I am trying to run my React application, it compiles successfully (with warnings) but get this error message when I try to click the button.

Here is my App.js:

import React from "react";
import { Component } from "react";
import { Button } from "react-bootstrap";
import Gift from "./Gift.js";

export default class App extends Component {
  constructor() {
    super();

    this.state = { gifts: [] };
  }

  addGift = () => {
    const { gifts } = this.state;

    const ids = this.state.gifts.map(gift => gift.id);

    const max_id = ids.length > 0 ? Math.max(ids) : 0;

    gifts.push({ id: max_id + 1 });

    this.setState({ gifts });
  };

  removeGift = id => {
    const gifts = this.state.gifts.filter(gift => gift.id !== id);
    this.setState = { ...gifts };
  };

  render() {
    return (
      <div>
        <h2>Gift Giver</h2>
        <div className="gift-list">
          {this.state.gifts.map(gift => {
            return (
              <Gift key={gift.id} gift={gift} removeGift={this.removeGift} />
            );
          })}
        </div>
        <Button className="btn-add" onClick={this.addGift}>
          Add Gift
        </Button>
      </div>
    );
  }
}

The component that I am importing:

import React from "react";
import { Component } from "react";
import {
  Form,
  FormGroup,
  FormControl,
  ControlLabel,
  Button
} from "react-bootstrap";

export default class Gift extends Component {
  constructor() {
    super();
    this.state = { person: "", present: "" };
  }
  render() {
    return (
      <div>
        <Form>
          <FormGroup>
            <ControlLabel>Person</ControlLabel>
            <FormControl
              onChange={event => this.setState({ person: event.target.value })}
              className="input-person"
            />
            <ControlLabel>Present</ControlLabel>
            <FormControl
              onChange={event => this.setState({ present: event.target.value })}
              className="input-present"
            />
          </FormGroup>
        </Form>
        <Button
          className="btn-remove"
          onClick={() => this.props.removeGift(this.props.gift.id)}
        >
          Remove Gift
        </Button>
      </div>
    );
  }
}

I get this warning compilation Trace: The node type SpreadProperty has been renamed to SpreadElement at Object.isSpreadProperty (C:\Users\ForAHumanPerson\Desktop\react_tdd\react-quick-start\node_modules@babel\types\lib\validators\generated\index.js:4512:11) at hasSpread (C:\Users\ForAHumanPerson\Desktop\react_tdd\react-quick-start\node_modules\babel-plugin-transform-object-rest-spread\lib\index.js:38:13) at PluginPass.ObjectExpression (C:\Users\ForAHumanPerson\Desktop\react_tdd\react-quick-start\node_modules\babel-plugin-transform-object-rest-spread\lib\index.js:234:14) at newFn (C:\Users\ForAHumanPerson\Desktop\react_tdd\react-quick-start\node_modules@babel\traverse\lib\visitors.js:179:21) at NodePath._call (C:\Users\ForAHumanPerson\Desktop\react_tdd\react-quick-start\node_modules@babel\traverse\lib\path\context.js:55:20) at NodePath.call (C:\Users\ForAHumanPerson\Desktop\react_tdd\react-quick-start\node_modules@babel\traverse\lib\path\context.js:42:17) at NodePath.visit (C:\Users\ForAHumanPerson\Desktop\react_tdd\react-quick-start\node_modules@babel\traverse\lib\path\context.js:90:31) at TraversalContext.visitQueue (C:\Users\ForAHumanPerson\Desktop\react_tdd\react-quick-start\node_modules@babel\traverse\lib\context.js:112:16) at TraversalContext.visitSingle (C:\Users\ForAHumanPerson\Desktop\react_tdd\react-quick-start\node_modules@babel\traverse\lib\context.js:84:19) at TraversalContext.visit (C:\Users\ForAHumanPerson\Desktop\react_tdd\react-quick-start\node_modules@babel\traverse\lib\context.js:140:19)

And also get a similar warning to the Uncaught Error during testing with Jest.

Upvotes: 0

Views: 145

Answers (1)

tomen
tomen

Reputation: 539

The problem with this line:

  removeGift = id => {
    const gifts = this.state.gifts.filter(gift => gift.id !== id);
    this.setState = { ...gifts }; <---------------
  };

this.setState is a method in React. You have to call it with

this.setState({gifts});

spread operation (...) here is not necessary since gifts is already an array.

Upvotes: 0

Related Questions