Noctisdark
Noctisdark

Reputation: 348

ReactJS remove component

I'm trying to learn the basics of facebook's react.js library and I've been lately thinking about a few stuff I can do with it just to get used to the way it works . I'm trying to make a div that contains 2 buttons one is OPEN and the other is CLOSE, when you click the OPEN the react will render a div containing anything (Like a msg saying "You clicked"), this is fine up to now but I cannot figure out how to make it disappear once clicked on the CLOSE button, does anyone know how to do that ? Thanks ^^

Upvotes: 0

Views: 1800

Answers (2)

molson504x
molson504x

Reputation: 1200

Here's how I would do this:

var foo = React.CreateClass({
    getInitialState: function() {
        return {
            showDiv: false, //Or true if you need it displayed immediately on open
        }
    },
    showIt: function() {
        this.setState({showDiv: true});
    },
    hideIt: function() {
        this.setState({showDiv: false});
    },

    render: function() {
        return (<div style={{display: this.state.showDiv ? 'block' : 'none'}}>Your content here</div>);
    }
});

What this will do is on state change, the style block of the div will be re-evaluated. If the showDiv state variable is true, it'll display as a block element. Otherwise it'll display none. You could, in theory, do this with CSS as well.

Here's a jsFiddle showing this being done with both CSS classes AND the style attribute on the div element.

Upvotes: 1

VB_
VB_

Reputation: 45682

There are at least four ways, that depends on the real problem you need to solve:

1) Add #your-div-id.hidden { display:none } styles and add/remove hidden class on click (maybe not React way)

2) Change view state (i.e. opened flag). That's a React way and maybe the simplest choice

onOpen() {
  this.setState({ opened: true });
}

onClose() {
  this.setState({ opened: false });
}

render() {
  var div = (this.state.opened) ? (<div>Your Div Content</div>) : undefined;
  return (
    //some your view content besides div
    {div}
  );
}

3) If you use Flux. Move state to Store and subscribe to changes. That maybe useful if you gonna show your div at many parts of your app (i.e. implement error popups which may be shown at any part of an application).

So, first of all let's keep warnings at the store:

var CHANGE_EVENT = 'change';
const warnings = [];

var WarningsStore = assign({}, EventEmitter.prototype, {
  getWarnings: () => return warnings,

  emitChange: () => this.emit(CHANGE_EVENT),

  addChangeListener: callback => this.on(CHANGE_EVENT, callback),

  removeChangeListener: callback => this.removeListener(CHANGE_EVENT, callback)
});

WarningsStore.dispatchToken = AppDispatcher.register(action => {

  switch(action.type) {
    case ActionTypes.ADD_WARNING:
      warnings.push(action.warning);
      WarningsStore.emitChange();
      break;
    case ActionTypes.DISMISS_WARNING:
      _.remove(warnings, {type: action.warningType}); //that's lodash or underscore method
      WarningsStore.emitChange();
      break;
  }
});

After we have a warnings store, you may subscribe to it from YourView and show popup on each AppDispatcher.dispatch({type: ADD_WARNING, warningType: 'Error'});

var YourView = React.createClass({

  componentDidMount: function() {
    WarningsStore.addChangeListener(this._onChange);
  },

  componentWillUnmount: function() {
    WarningsStore.removeChangeListener(this._onChange);
  },

  _onChange() {
    this.setState({ warnings: WarningsStore.getWarnings() });
  },

  render() {
    //if we have warnigns - show popup
    const warnings = this.state.warnings,
          onCloseCallback = () => AppDispatcher.dispatch({type: DISSMISS_WARNING, warningType: warnings[0].warningType});
          popup = (warnings.length) ? <YourPopupComponent warning={warnings[0]} onClose={onCloseCallback}> : undefined;

    return (
      //here the main content of your view
      {popup}
    );
  }

})

4) If you simplified your example, but actually instead of div you need to show/hide another page - you should use react-router

Upvotes: 5

Related Questions