please i am building a FAQs page and i made a series of buttons which when clicked displays a hidden paragraph underneath each button, now the issue is all buttons respond to one button being clicked on and they all display their respective paragraphs, i want each button to display it's own hidden paragraph alone.
this is the react code i used
class FAQ extends React.Component {
constructor () {
super()
this.state = {
isHidden: true,
}
}
toggleHidden () {
this.setState({
isHidden: !this.state.isHidden})
}
<div className="faq--button">
<button onClick={this.toggleHidden.bind(this)}>button to click</button>
{!this.state.isHidden && <p>lorem ipsum"</p>}
</div>
Currently isHidden is used for all buttons, which will have the same effect in each button. So you need to add separate states for each button. Like isHidden2, isHidden3....
Related
I am trying to toggle two div on the basis of a click on button , the issue is I have kept the state false in constructor
class App extends Component {
constructor(props){
super(props);
this.flipScreen = this.flipScreen.bind(this);
this.state = {
hideDashBoard: false,
hideContractScreen:true,
}
}
}
flipScreen(){
this.setState({hideDashBoard: true});
this.setState({hideContractScreen: false});
}
the html in render function
<div className={this.state.hideContractScreen ? 'hidden' : ''} style = {{position:"absolute",left:"250px",top:"50px"}}class="row">
<div className={this.state.hideDashBoard ? 'hidden' : 'show'} style = {{position:"absolute",left:"250px",top:"50px"}}class="row">
<span onClick={this.flipScreen} className="startProposal">
Start Proposal
</span>
Both the divs are present on the screen when the screen is loaded initially but on click of button the div with hidedashboard condition get classname as hidden
I'm trying to toggle some styling depending on whether the navbar is opened or closed (in mobile and tablet views), I have seen solutions for jQuery but i want to do it in react js.
i have tried setting a state on the hamburger button and toggling it on user interaction but it's really not a good solution and it's flawed since sometimes the user can close the navbar without clicking the hamburger button, instead i want to get the actual state of the navbar
is this possible in react js? if so how?
Use a boolean state variable and toggle it when the Hamburger is clicked...
...
constructor(props) {
super(props);
this.state = { showNav: true };
this.toggleNav = this.toggleNav.bind(this);
}
toggleNav() {
this.setState({
showNav: !this.state.showNav
})
}
In the Navbar markup...
<nav>
<button className="navbar-toggler" type="button" onClick={this.toggleNav}>
<span className="navbar-toggler-icon"></span>
</button>
<div className={(showNav ? 'show' : '') + ' collapse navbar-collapse'}>
</div>
</nav>
Demo: https://codeply.com/p/z0rSHluhPi
I want to show different popovers on different listitems using reactstrap but on state change the property of popover become true and show all popovers are displayed rather than just one that i clicked.
//setting popoveropen:false initially
this.state = {
popoverOpen: false
};
//on click this toggle function runs which change the popoverOpen state to true which displays all the popover
toggle() {
this.setState({
popoverOpen: !this.state.popoverOpen
})
}
//this is the jsx section where i have used popovers in list items on click of which the toggle function runs and change the popoverOpen State to true
render(){
return(
Members
Popover Title
body1
<ListGroupItem tag="button" id="Popover2" onClick=
{this.toggle2}>Labels<Popover placement="left" isOpen=
{this.state.popoverOpen}
target="Popover2" toggle={this.toggle}>
<PopoverHeader>Popover Title</PopoverHeader>
<PopoverBody>body2</PopoverBody>
</Popover>
</ListGroupItem>
</ListGroup>)}
just logic is missing in this code
I'm working with React MDL library, and I used pre-defined components like FABButton
<FABButton>
<Icon name="add"/>
</FABButton>
And it shows the button as in the image bellow:
Now, what I want is showing a dialog with the + icon... not as what happens here:
This happened after this code:
<FABButton>
<AddingProject />
<Icon name="add" />
</FABButton>
The class of dialog is as follows:
class AddingProject extends Component {
constructor(props) {
super(props);
this.state = {};
this.handleOpenDialog = this.handleOpenDialog.bind(this);
this.handleCloseDialog = this.handleCloseDialog.bind(this);
}
handleOpenDialog() {
this.setState({
openDialog: true
});
}
handleCloseDialog() {
this.setState({
openDialog: false
});
}
render() {
return (
<div>
<Button colored onClick={this.handleOpenDialog} raised ripple>
Show Dialog
</Button>
<Dialog open={this.state.openDialog} onCancel={this.handleCloseDialog}>
<DialogTitle>Allow data collection?</DialogTitle>
<DialogContent>
<p>
Allowing us to collect data will let us get you the information
you want faster.
</p>
</DialogContent>
<DialogActions>
<Button type="button">Agree</Button>
<Button type="button" onClick={this.handleCloseDialog}>
Disagree
</Button>
</DialogActions>
</Dialog>
</div>
);
}
}
export default AddingProject;
The above code is with the required import statements
This works with me....
First step: I added the component of the modal as follows:
<FABButton>
<Icon name="add" />
</FABButton>
<ProjectModal>
Second step: I added this prop: visible for the component as here:
<ProjectModal visible={this.state.showDialog} />
And here you need to add showDialog to the states in your class with false.
state = {
showDialog: false
};
Now, to step 3.
Third step: Add this part to your code, to be called when you click.
openModal = () => {
this.setState({ showDialog: true });
};
On the other side, you need to implement onClick in the button as follows:
<FABButton onClick={this.openModal.bind(this)}>
<Icon name="add" />
</FABButton>
Fourth step: In the modal/dialog class, you need to store the visible in a new state variable, which is here showDialogModal
constructor(props, context) {
super(props, context);
this.state = {
showDialogModal: this.props.visible
};
}
Now, you need to pass the changed state from the first class to the modal/dialog class, there are more than one option that React gives you, I used this one in fifth step. Fifth step: use this React event componentWillReceiveProps as below.
componentWillReceiveProps(nextProps) {
if (this.props.showDialogModal != nextProps.visible) {
this.setState({
showDialogModal: nextProps.visible
});
}
}
This will reflect any change in visible property from the first class to our new one here which is showDialogModal
Now in the render part, you need to check the docs of your components, here I started with React-Bootstrap.
Sixth step: use the show property in your component.
<Modal show={this.state.showDialogModal} onHide={this.closeModal}>
onHide is for closing the dialog, which makes you need to implement this too.
closeModal = () => {
this.setState({ showDialogModal: false });
};
Finally, in the closing button, add this:
<Button onClick={this.closeModal.bind(this)}>Close</Button>
Good luck.
I am using React 16.1.1 (with the react-rails gem) in a Rails 5.1 app.
The React components on a specific page work fine, except when going back to this page with the browser 'back' button (tested with firefox / chrome / safari). In that case, the display is inconsistent with the state of the component. I've setup a demo of the problem: https://lit-bastion-28654.herokuapp.com/.
Steps to reproduce:
be on /page1
click the 'selection mode' button, it sets 'selectionMode' to true
click 'page 2'
use 'back' button to go back to page 1
EXPECTED BEHAVIOUR: the button is grey (selectionMode is reset to false when component loaded). OBSERVED BEHAVIOUR: the button is still blue?!
There, you can see that the button is blue, as if selectionMode was true, but the react browser plugin shows that selectionMode is false. The React browser plugin shows false information: it shows that the button does not have the 'btn-primary' class (which is normal if selectionMode is false), but you can obviously see that in the DOM, it has the 'btn-primary' class, since it is appears blue.
This is my code:
page1.html.erb:
<%= react_component("EditableCardList", { editable: true }) %>
editable_card_list.js.jsx:
class EditableCardList extends React.Component {
constructor(props) {
super(props);
this.state = {
selectionMode: false
};
this.toggleSelectionMode = this.toggleSelectionMode.bind(this);
}
toggleSelectionMode() {
this.setState(prevState => ({ selectionMode: !prevState.selectionMode }));
}
render() {
if (this.props.editable === true)
return (
<div>
<div className="row card-buttons">
<div className="col-md-12">
<div className="pull-left">
<ManageCardsButtons
selectionMode={this.state.selectionMode}
toggleSelectionMode={this.toggleSelectionMode}
/>
</div>
</div>
</div>
</div>
)
}
}
manage_cards_buttons.js.jsx:
class ManageCardsButtons extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<span>
<button type="button" className={`btn btn-default btn-sm ${this.props.selectionMode ? 'btn-primary' : ''}`} onClick={this.props.toggleSelectionMode}>Selection mode</button>
{ this.props.selectionMode && <span>selection mode</span> }
</span>
)
}
}
So my question is: How to make sure that, after using 'back' in the browser, the button is rerendered properly (and appears grey instead of blue)?
The issue may be related with turbolinks and caching, but I've not been able to figure it out yet.
React and TurboLinks conflict, so my final solution was to disable TurboLinks caching on that specific page.
When you go back to page1, Component rerenders, and sets the default selectionMode which is false in your case.
you can use redux.
you can save selectionMode to your
localStorage when it changes, and by default load it from the
storage.