I wouldlike to change my view when I click on one Button :
render(){
return(
<div className="button-toolbar">
<button className="button">Button 1</button>
<button className="button">Button 2</button>
<button className="button">Button 3</button>
<View1></View1>
<View2></View2>
<View3></View3>
</div>
)
For example when I click on the button 1, only View1 is active.
If I click on Button 2 ==> View 2
If I click on Button 3 ==> View 3
PS : View1, View2 and View3 are component file (.jsx)
There are multiple ways to do this. You can set flags around the views. For example
render(){
return(
<div className="button-toolbar">
<button className="button" onClick={() => setState({view: 1})}>Button 1</button>
<button className="button" onClick={() => setState({view: 2})}>Button 2</button>
<button className="button">Button 3</button>
{this.state.view === 1 ? <View1></View1> : ''}
{this.state.view === 2 ? <View2></View2> : ''}
<View3></View3>
</div>
)
Do it like this:
render(){
return(
<div className="button-toolbar">
<button className="button" onClick={() => setState({view: 1})}>Button 1</button>
<button className="button" onClick={() => setState({view: 2})}>Button 2</button>
<button className="button" onClick={() => setState({view: 3})}>Button 3</button>
{this.state.view === 1 ? <View1/> :this.state.view === 2? <View2/>:this.state.view === 3?<View3/>:''}
</div>
)
If you're using class approach you could do something like this
class Test extends React.Component {
state = {
currentView: 1
}
setCurrentView(viewNumber) {
this.setState({ currentView: viewNumber });
}
render(){
return(
<div className="button-toolbar">
<button
className="button"
onClick={() => this.setCurrentView(1)}
>Button 1</button>
// in the rest just change the number
{
this.state.currentView === 1
? <View1/>
: // (and so on)
}
</div>
)
You can create a simple array to generate buttons and add method to class to remove this part
{
this.state.currentView ...
}
from jsx.
Before next questions like this, please visit official React docs.
This can be achieved in multiple ways.
Achieving it using hooks approach (using state)
Use the react's useState - active .
Active View will be decided based upon the value of active value. Thus creating the reactivity b/w active and the view to be rendered.
I have created a sample code in codesandbox . You can refer - Link
const [active, setActive] = React.useState(1);
const SetView = (active) => {
setActive(active);
};
const ActiveView = () => {
switch (active) {
case 1:
return <View1 />;
case 2:
return <View2 />;
default:
return <View3 />;
}
};
return (
<div className="button-toolbar">
<button className="button" onClick={() => SetView(1)}>
Button 1
</button>
<button className="button" onClick={() => SetView(2)}>
Button 2
</button>
<button className="button" onClick={() => SetView(3)}>
Button 3
</button>
{ActiveView()}
</div>
);
You can learn more about the React Hooks in the article - https://reactjs.org/docs/hooks-intro.html
Related
I'm trying to make multiple toggles buttons, and whenever the user clicks on any one of them, then I want it to become a bit darker. So, that user knows which one they've clicked.
Here's sample code I've written.
CODE:
import React, { useState } from "react";
import "./styles.css";
export default function App() {
const [active, setActive] = useState("first");
return (
<>
<div className="App">
<button className="button" active={active === "first"} onClick={() => {setActive("first"); }} >first</button>
<button className="button" active={active === "Second"} onClick={() => {setActive("Second"); }} >Second</button>
<button className="button" active={active === "Third"} onClick={() => {setActive("Third"); }} >Third</button>
</div>
</>
);
}
Now, How do I make an OnClick function that holds the after Click? functionality?
You can do it like this:
<button
className={`button ${active === "first" ? "activeButton" : ""}`}
onClick={() => {
setActive("first");
}}
>
first
</button>
<button
className={`button ${active === "Second" ? "activeButton" : ""}`}
onClick={() => {
setActive("Second");
}}
>
Second
</button>
<button
className={`button ${active === "Third" ? "activeButton" : ""}`}
onClick={() => {
setActive("Third");
}}
>
Third
</button>
And then in you css file:
.activeButton {
background-color: red;
}
I have a CSS module called styles and this React code. It's a div with two buttons inside. I use the isMenuActive state to verify if the menu is active or not. If it is active, the CSS class 'active' gets in and the menu appears, otherwise not.
<div className={`${styles.customerOptionsMenu} ${isMenuActive ? styles.active : null}`}>
<button onClick={() => { console.log('hi') }}>
<span className="material-icons">edit</span>Editar
</button>
<button onClick={() => {console.log('hi')}}>
<span className="material-icons">delete</span>Deletar
</button>
</div>
When I click the buttons, nothing happens.
But If I store the button as a global variable in developer tools and run button.click() it works fine if I remove the template literals:
<div className={styles.customerOptionsMenu + styles.active}>
<button onClick={() => { console.log('hi') }}>
<span className="material-icons">edit</span>Editar
</button>
<button onClick={() => {console.log('hi')}}>
<span className="material-icons">delete</span>Deletar
</button>
</div>
It works fine.
Why??? And what should I do to keep changing the classes when isMenuActive changes?
Edit: Full code with the button that changes isMenuActive
const [isMenuActive, setIsMenuActive] = useState(false)
const onBlur = () => { setIsMenuActive(!isMenuActive)}
return(
<td>
<button onBlur={onBlur} className={styles.customerOptions} onClick={() => setIsMenuActive(!isMenuActive)}>
<span className="material-icons">more_horiz</span>
</button>
<div className={`${styles.customerOptionsMenu} ${isMenuActive ? styles.active : null}`}>
<button onClick={() => { console.log('hi') }}>
<span className="material-icons">edit</span>Editar
</button>
<button onClick={() => {console.log('hi')}}>
<span className="material-icons">delete</span>Deletar
</button>
</div>
</td>
)
New edit: The answer is in the comments by Pandaiolo. The problem was the onBlur={onBlur} code, when I removed it from the button everything worked fine!
To handle changing classnames you can use the classnames package to do something like this:
import cx from "classnames";
<div className={cx(styles.customerOptionsMenu, { styles["active"]: isMenuActive })}>
<button onClick={() => { console.log('hi') }}>
<span className="material-icons">edit</span>Editar
</button>
<button onClick={() => {console.log('hi')}}>
<span className="material-icons">delete</span>Deletar
</button>
</div>
I think the space is fine in your template literal, because it references two different class names. You probably want to use ${isMenuActive ? styles.active :''} otherwise null becomes the string "null", which is probably harmless unless you have a class .null that applies some styles, but that is basically not what you want.
But maybe the onBlur is called after the click?
click
button becomes focus
button blurs ?
Not sure. But in that case it would toggle the state two times, cancelling its effect. Maybe try with just the onClick and without the onBlur at first?
And you can add a console.log('isMenuActive', isMenuActive) before the return statement to see it's value along rerenders, see if it matches what you expect.
The isMenuActive is not defined. Place it in as a parameter as so:
export default function App(isMenuActive) {
return (
<div className="App">
<div className={`${styles.customerOptionsMenu} ${isMenuActive ? styles.active : null}`}>
<button onClick={() => { console.log('hi') }}>
<span className="material-icons">edit</span>Editar
</button>
<button onClick={() => {console.log('hi')}}>
<span className="material-icons">delete</span>Deletar
</button>
</div>
</div>
);
}
I'm using Material UI for the icons for connect and disconnect.
I want the application to swap between these two icons onClick.
I'm new to React, but haven't any helpful resources yet.
Here's the code as it is so far:
{ user.connected ?
(
<Button color="info" simple size="sm">
<PersonAddDisabled className={classes.footerIcons} /> Disconnect
</Button>
)
:
(
<Button color="info" size="sm">
<PersonAdd className={classes.footerIcons} /> Connect
</Button>
)
}
As it is above, I am address whether they are connected or not, but I'm not sure how to implement a toggle of those two buttons, where onClick it will switch between the two.
here is a code
Your state
state = {
connected: true
}
onClickButton(){
this.setState(prevState => {connected: !this.prevState.connected})
}
Your code
{ this.state.connected ?
(
<Button color="info" simple size="sm" onClick={ this.onClickButton }>
<PersonAddDisabled className={ classes.footerIcons } /> Disconnect
</Button>
)
:
(
<Button color="info" size="sm" onClick={ this.onClickButton }>
<PersonAdd className={ classes.footerIcons } /> Connect
</Button>
)
}
I am using a button in my react component and it's onClick callback is never triggering. The component is generated based on data in a .map function and it looks and behaves correctly other than the button. I have two buttons (flagged in code), neither of which work. Here is the code:
var namesList = this.state.data.map(function(name, index){
return (
<div>
<a class="btn" onCLick={() => alert('alert')} style={{width: '70%', marginTop: '33px'}}>
<span>click</span>
</a>
<button onCLick={() => alert('alert')} > button </button>
</div>
);
})
Why is this the case?
I see a typo here:
onCLick={() => alert(‘alert’)}
Should be:
onClick={() => alert('alert')}
In my hangman game, the player can click
a letter(button)
and the guessed letter shows
if correct it is appended to the hidden word (_ _ _ _ )
but I would like to refactor a long list of buttons
into a simple map function
that creates a button for every letter in the array (i.e the Alphabet)
ideally, the button would disappear after it has been clicked.
something like:
arr = [alphabet]
arr.map(letter=>{
return <button>{letter}</button>
})
but I can't figure out how to convert my list into such a function
export class Input extends Component {
handleClick = (event) => {
if (this.props.guesses.includes(event.target.value)) {
} else {
this.props.makeGuess(event.target.value.toLowerCase())
}
// event.target.setAttribute('disabled', '')
}
render() {
return (<div>
<button onClick={this.handleClick} value="A">A</button>
<button onClick={this.handleClick} value="B">B</button>
<button onClick={this.handleClick} value="C">C</button>
<button onClick={this.handleClick} value="D">D</button>
<button onClick={this.handleClick} value="E">E</button>
<button onClick={this.handleClick} value="F">F</button>
<button onClick={this.handleClick} value="G">G</button>
<button onClick={this.handleClick} value="H">H</button>
<button onClick={this.handleClick} value="I">I</button>
<button onClick={this.handleClick} value="J">J</button>
<button onClick={this.handleClick} value="K">K</button>
<button onClick={this.handleClick} value="L">L</button>
<button onClick={this.handleClick} value="M">M</button>
<button onClick={this.handleClick} value="N">N</button>
<button onClick={this.handleClick} value="O">O</button>
<button onClick={this.handleClick} value="P">P</button>
<button onClick={this.handleClick} value="Q">Q</button>
<button onClick={this.handleClick} value="R">R</button>
<button onClick={this.handleClick} value="S">S</button>
<button onClick={this.handleClick} value="T">T</button>
<button onClick={this.handleClick} value="U">U</button>
<button onClick={this.handleClick} value="V">V</button>
<button onClick={this.handleClick} value="W">W</button>
<button onClick={this.handleClick} value="X">X</button>
<button onClick={this.handleClick} value="Y">Y</button>
<button onClick={this.handleClick} value="Z">Z</button>
</div>)
}
}
Your render method should be:
render() {
const alphabet = [...'ABCDEFGHIJKLMNOPQRSTUVWXYZ'];
return (
<div>
{alphabet.map((letter, index) => <button key={} onClick={this.handleClick} value={letter}>{letter}</button>)}
</div>
);
}
You can simply have a function scoped under render that creates the array of elements you want to render. Try this:
export class Input extends Component {
render() {
function buttonList() {
const alphabet = 'abcdefghijklmnopqrstuvwxyz'.split('');
return alphabet.map(letter => {
return <button onClick={this.handleClick} key={letter}>{letter}</button>
});
}
return (
<div>{buttonList()}</div>
);
}
}
You also need to set the key value on each of the elements or you will get a React warning.
Here is an example of a complete component that filters the letters out:
export class Input extends Component {
constructor() {
super()
this.state = {
letters: [/* the letters */],
}
}
handleClick = letter => () => {
this.props.makeGuess(letter.toLowerCase())
this.setState({ letters: this.state.letters.filter(l => l !== letter) })
}
render() {
return (<div>
{this.state.letters.map(letter =>
<button key={letter} onClick=this.handleClick(letter)>{letter}</button>
)}
</div>
}
}
This example initializes state with all of the letters then uses currying to create a custom click handler for each button based on the letter passed in. The functions filter out their letter and update state causing a re-render without that letter. This way there is no need to use value or deal with the event at all.
Here's an example of how to iterate over your array of letters and output a button for each of them:
export class Input extends Component {
const handleClick = e => {
// Your logic here...
};
const alphabet = [ // Letters of the alphabet... ];
const buttons = alphabet.map(letter => (
<button value={letter} onClick={handleClick}>
{letter}
</button>
));
return <div>{buttons}</div>;
}