Reputation: 83
I have a QWERTY keyboard rendered dynamically through a component as Bootstrap buttons through bootstrap-react. They do not have IDs I'm trying to NOT use IDs as a crutch in React.
When one of the letters is clicked it fires off an onClick event through props, back to my App.js. This works fine. I want that button to then be disabled. Since it doesn't have an ID and I can't do a jQuery class& data- value selector because: React.
How can I change that buttons property to Disabled (Disabled is an allowable HTML property in react).
import React from "react";
import {Button} from 'react-bootstrap';
const keyboard = props => {
return (
<div>
{props.keyboard.keys.map((item,index) => (
<Button bsStyle={props.keyboard.style} bsSize="large" onClick={props.click} key={index} value={item.toUpperCase()}> {item.toUpperCase()}
</Button>
))}
</div>
)
}
export default keyboard;
My click event is so far working as intended. Ideally I'd like the Button to change to:
<Button bsStyle={props.keyboard.style} bsSize="large" onClick={props.click} key={index} value={item.toUpperCase()} disabled> {item.toUpperCase()}</Button>
after the click event.
The keyboard is referenced from my App.js as follows:
<Panel header="Keyboard:">
<Keyboard keyboard={this.keyboard.row1} click={(event) => this.keyboardClickHandler(event)}
/>
<Keyboard keyboard={this.keyboard.row2} click={(event) => this.keyboardClickHandler(event)}/>
<Keyboard keyboard={this.keyboard.row3} click={(event) => this.keyboardClickHandler(event)}/>
<div id="messages">{this.messages}</div>
</Panel>
and the click handler console.logs the values as expected:
keyboardClickHandler = (event) => {
console.log(event.target.value)
}
*** Edit:
I kinda hacked it in there, because I was having trouble passing event data back through the super component. I reverted back to a simple component, and added an array of the keys in state holding boolean values, and a check inside the component to see if it should be disabled.
status: {
q: false,
w: false,
e: false,
r: false,
t: false,
y: false,
u: false,
i: false,
o: false,
p: false
And the component:
import React from "react";
import {Button} from 'react-bootstrap';
const keyboard = props => {
return (
<div>
{props.keyboard.keys.map((item,index) => {
let status = props.keyboard.status[item]
return (
<Button bsStyle={props.keyboard.style} bsSize="large" onClick={props.click} key={index} disabled={status} value={item}> {item.toUpperCase()}
</Button>
)
}
)
}
</div>
)
}
export default keyboard;
Upvotes: 6
Views: 12818
Reputation: 20885
React works differently than jQuery for sure. Here are the steps you need to undertake in order to achieve what you want:
class
component to have access to it's state.Here is some pseudo code
class keyboard extends React.Component {
constructor(props) {
super(props);
// Set your initial disabled state here
this.state = {
buttonDisabled: false
};
// Bind your click handler
this.onButtonClick = this.onButtonClick.bind(this);
}
render() {
return <Button onClick={this.onButtonClick} disabled={this.state.buttonDisabled} />;
}
onButtonClick(event) {
// call your existing click event
this.props.click(event);
// Disable your button here
this.setState({buttonDisabled: true});
}
}
Upvotes: 5
Reputation: 1376
It requires some reworking of your component, but one straightforward method that comes to mind would be to store a map of all of the key items in the state (could be in parent component or keyboard component) with the item as the key and a boolean as they value. Then, in your onClick handler, you can pass the item key and set the state to false for that given key.
So first, let's change your onClick handler to
onClick={item => props.onClick(item)}
Then in the parent component, or wherever you decide to define the state and onClick handler:
// parent component
constructor(props) {
super(props);
this.state = {
a: false,
b: false,
...
}
onClick(itemKey) {
this.setState({ itemKey: false});
}
You can then pass this state object to keyboard as a prop and, for each button in your map function, access the corresponding value for your item. Finally, you will need to add the disabled attribute to the button component in your map function. As you may know, in JSX you can execute javascript within brackets like so {'first' + 'last'}
. Therefore, once you have passed down the map from the parent component state, just change add the following to your button:
disabled={{keyboard.props.[whateverYouNameThisStateProp][item]}}
Also, don't forget to set the key={}
attribute to a unique value for the buttons you are iterating over.
Sorry if that's a little disorganized, let me know if I anything is unclear!
Upvotes: 0