Reputation: 348
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
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
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