Antonio Pavicevac-Ortiz
Antonio Pavicevac-Ortiz

Reputation: 7759

Handler not working as expected in child component in React

I am on the last spec in a section of a test from school.

select should have an onChange event that submits the new animal

Essentially I can't seem to get the handleSubmit function passed into the child, to respond to the changes... This is the rest of the spec.

it('select should have an onChange event that submits the new animal', () => {
  expect(animalSelect.props('select').onChange).to.be.function;

  // choosing a random animal
  let animal = getRandomAnimal();

   // simulating a 'change' event with an event described as the second argument given to `simulate`
   animalSelect.find('select').simulate('change', { target: { value: animal } });

   // the spy sent in should be called with the argument described
   expect(setAnimalSpy.calledWith(animal)).to.be.true;
 });

This is the parent component Exhibit:

import React, { Component } from 'react';
import AnimalSelect from './AnimalSelect';
import Cage from './Cage';

export default class Exhibit extends Component {
  constructor(props) {
    super(props);
    this.state = {
      selectedAnimal: this.props.selectedAnimal,
    };
    this.setAnimal = this.setAnimal.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  setAnimal(animal) {
    this.setState({ selectedAnimal: animal });
  }

  handleSubmit(event) {
    this.setState({ selectedAnimal: event.target.value });
  }

  render() {
    const { selectedAnimal } = this.state;
    return (
      <div className="exhibit">
        <AnimalSelect handleSubmit={this.handleSubmit} submitAnimal={this.setAnimal} animals={this.props.animals} />
        <Cage selectedAnimal={selectedAnimal} />
      </div>
    );
  }
}

This is the AnimalSelect (The child of Exhibit) component:

import React, { Component } from 'react';

// exporting the constructor function (dumb component).
// what is the parameter coming in here?
export default function AnimalSelect(props) {
  // prettier-ignore
  return (
    <form>
      <label>Select an Animal: </label>
      <select onChange={() => props.handleSubmit}>
        {props.animals.map((animal, index) => {
          return (
            <option key={animal} value={animal}>
              {animal}
            </option>
          );
        })}
      </select>;
    </form>
  );
}

Unfortunately this is the only error I am getting.

    AssertionError: expected false to be true

Any ideas?

Upvotes: 1

Views: 249

Answers (1)

Rich Churcher
Rich Churcher

Reputation: 7664

Here, you set the event handler to be an anonymous function which returns a reference to a function:

<select onChange={() => props.handleSubmit}>

You probably intend something more like this:

<select onChange={evt => props.handleSubmit(evt)}>

This effectively delegates the event handler to the parent component's function, passing the event object along to it. Although I'm uncertain why setting the handler as suggested in the comment didn't work.

Upvotes: 1

Related Questions