Guilherme Oderdenge
Guilherme Oderdenge

Reputation: 5001

Unmount children not triggering componentWillUnmount

The problem

The React.unmountComponentAtNode within unmountInput of InputsList.jsx isn't triggering the componentWillUnmount within Input.jsx.

The code

This is the entire code of InputsList.jsx:

//...
getInitialState: function () {
  return {
    keyRefs: []
  };
},
handleKeyRefs: function () {
  var index = 0;

  this.props.inputs.keys.forEach(function () {
    this.state.keyRefs.push('key-' + index++);
  }.bind(this));
},
componentWillMount: function () {
  this.handleKeyRefs();
},
render: function () {
  return (
    <section className="inputs">
      <ul>
        {this.props.inputs.keys.map(this.renderInput)}
      </ul>
    </section>
  );
},
renderInput: function (key, index) {
  return <Input representation={key.representation} code={key.code} ref={this.state.keyRefs[index]} key={index} />;
},
componentDidMount: function () {
  var inputs  = this.props.inputs.keys
      , index = 0;

  $(window).on('keypress', function (event) {
    if (event.keyCode === inputs[0].code) {
      inputs.shift();

      this.unmountInput(index++);
    };
  }.bind(this));
},
unmountInput: function (index) {
  return React.unmountComponentAtNode(React.findDOMNode(this.refs['key-' + index]));
}
//...

Input.jsx:

var Input = React.createClass({
  propTypes: {
    representation: React.PropTypes.string
  },
  render: function () {
    return (
      <li className="input">{this.props.representation}</li>
    );
  },
  componentWillUnmount: function () {
    console.log('unmounted!');
  }
});

module.exports = Input;

Suggestions?

Upvotes: 3

Views: 2785

Answers (1)

Brigand
Brigand

Reputation: 86240

Don't use React.unmountComponentAtNode(node) unless you previously did React.render(stuff, node).

If you want to change the children of your component, you need to change your data (props/state) so that render gives the desired output.

Because you use this.props.inputs, your options are:

  • have the component using InputsList give an updated input prop
    • you probably want this
  • store enough data in state to allow this.props.input.keys.filter(someCondition).map(this.renderInput)

Read Thinking in React (maybe multiple times, I've read it at least 5).

Upvotes: 3

Related Questions