Toggle divs using class in react - reactjs

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

Related

All buttons close on click of one button

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....

react-bootstrap modal not reacting to property change

I am using React v18.1, react-bootstrap v2.4. I have a Modal component I am trying to get to display upon a button press. The modal component is quite simple:
class AdjustmentModal extends React.Component {
constructor(props) {
super(props);
this.state = {
'show': this.props.show
};
this.handleClose = this.handleClose.bind(this);
}
handleClose() {
this.setState({ show: false })
}
render() {
return (
<Modal show={this.state.show} onHide={this.handleClose}>
[ ... Modal Content Here ... ]
</Modal>
);
}
}
export default AdjustmentModal;
As you can see, I bind the modal's show property to the value of show in state.
Then, in the component in which I want to display my modal, I have the following:
// Within render() ...
<AdjustmentModal
show={this.state.showAdjustment}
partNo={this.state.partNo}
onHandQty={this.state.onHandQty}
/>
// Futher on in the code, display the modal on click:
<Button className="icon" onClick={this.handleDisplayAdjustment}>
<i className="bi bi-pencil-square"></i>
</Button>
handleDisplayAdjustment :
handleDisplayAdjustment(event) {
event.preventDefault();
this.setState({
showAdjustment : true
});
}
Now, despite the value showAdjustment in the parent component changing to true, the modal doesn't display.
I could set the <Modal show={this.props.show} .../> instead, but props are read-only, so there is no way to close the modal again if reading from props rather than state.
You can use props, which is a better way to handle this if you want to close it then pass a method from the parent which when called update the state in the parent to false and due state update the parent component will re render and though the child component that is the modal component and the Modal will get the updated value which will be false. below is the code on how you can achieve that.
closeModal() {
this.setState({
showAdjustment: false
})
}
// Within render() ...
<AdjustmentModal
show={this.state.showAdjustment}
partNo={this.state.partNo}
onHandQty={this.state.onHandQty}
onClose={this.closeModal.bind(this)}
/>
// Futher on in the code, display the modal on click:
<Button className="icon" onClick={this.handleDisplayAdjustment}>
<i className="bi bi-pencil-square"></i>
</Button>
For the child component
class AdjustmentModal extends React.Component {
handleClose() {
this.props.onClose()
}
render() {
return (
<Modal show={this.props.show} onHide={this.handleClose}>
[ ... Modal Content Here ... ]
</Modal>
);
}
}
export default AdjustmentModal;
EDIT: Explaining the approach
This will make your Modal component a Controlled component that is controlled by Parent, also updating props as a state inside the child component is not the right way, which may create potential bugs.

Setting value of badge to 0 after opening toggle

I am working on react chat widget and in this I am able to get the count of new messages I am getting in badge but I want to clear the batch value once I click on the hidden button
export default class App extends React.Component
{
constructor(props)
{
state = {
count:0
}
}
}
for incrementing the value
this.setState((old_state)=>{
let new_count = ++old_state.count;
return { count: new_count }
})
inside render function badge={this.state.count}
and launcher component looks like this
const Launcher = ({ toggle, chatOpened, badge, bgcolor }) =>
<button type="button" style={{backgroundColor : bgcolor}} className={chatOpened ? 'rcw-launcher rcw-hide-sm' : 'rcw-launcher'} onClick={toggle}>
{chatOpened ?
<img src={close} className="rcw-close-launcher" alt="" />:
<React.Fragment><Badge badge={badge} /><img src={openLauncher} className="rcw-open-launcher" alt="" /></React.Fragment>
}
</button>;
I am not able to understand how can I cange the value after reading messages once.
When chatOpened is true, set state count to 0. Or pass 0 to badge count;

inconsistent state and display in React when using browser 'back' button

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.

In React, Is it good practice to search for certain element in DOM?

Is it good to just specify className for element so i could find it later in the DOM through getElementsByClassName for manipulations?
Adding a class to find the DOM element? Sure you can do that, but refs are probably the better solution.
Manipulating the DOM element? That's an absolute no-go. The part of the DOM that is managed by React should not be manipulated my anything else but React itself.
If you come from jQuery background, or something similar, you will have the tendency to manipulate element directly as such:
<div class="notification">You have an error</div>
.notification {
display: none;
color: red;
}
.show {
display: block;
}
handleButtonClick(e) {
$('.notification').addClass('show');
}
In React, you achieve this by declaring what your elements (components) should do in different states of the app.
const Notification = ({ error }) => {
return error
? <div className="notification">You have an error</div>
: null;
}
class Parent extends React.Component {
state = { error: false };
render() {
return (
<div>
<Notification error={this.state.error} />
<button onClick={() => this.setState({ error: true })}>
Click Me
</button>
}
}
The code above isn't tested, but should give you the general idea.
By default, the state of error in Parent is false. In that state, Notification will not render anything. If the button is clicked, error will be true. In that state, Notification will render the div.
Try to think declaratively instead of imperatively.
Hope that helps.
When using React, you should think about how you can use state to control how components render. this.setState performs a rerender, which means you can control how elements are rendered by changing this.state. Here's a small example. I use this.state.show as a boolean to change the opacity of the HTML element.
constructor(props) {
super(props)
this.state = {
show: true
}
}
handleClick() {
this.setState({show: false})
}
render() {
const visibility = this.state.show ? 1 : 0
return (
<button style={{opacity: visibility} onClick={() => this.handleClick()}>
Click to make this button invisible
</button>
)
}

Resources