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')}
Related
In ReactJS I want to call an onClick function on a button to open another website but it doesn't work. The following excerpt of the code is:
import PageButton from "./components/PageButton";
const openInNewTab = (url) => {
window.open(url, "_blank", "noopener,noreferrer");
};
return (
<div className="App">
<div className="appNav">
<div className="my-2 buttonContainer buttonContainerTop">
<PageButton name={"Home"} isBold={true} />
<PageButton
name={"Test"}
onClick={() => openInNewTab("https://www.bing.com/")}
/>
</div>
</div>
</div>
import React from "react";
const PageButton = (props) => {
return (
<div className="btn">
<span className={props.isBold ? "pageButtonBold hoverBold" : "hoverBold"}>
{props.name}
</span>
</div>
);
};
export default PageButton;
It should open the Webpage when I click on it but it doesn't.
If you need PageButton to handle the click, you should forward the click handler down like so:
const PageButton = (props) => {
return (
<div className="btn" onClick={props.onClick}>
<span className={props.isBold ? "pageButtonBold hoverBold" : "hoverBold"}>{props.name}</span>
</div>
);
};
export default PageButton;
Also, I would suggest you transform the div to button as it's the right element for handling clicks.
can you use tag a inside the button like this
<button .... > <a href="..." target="_blank"> text<a/> </button>
At PageButton component, you need to add click event for Warpper.
const PageButton = (props) => {
return (
<div className="btn" onClick={props.onClick}>
<span className={props.isBold ? "pageButtonBold hoverBold" : "hoverBold"}>
{props.name}
</span>
</div>
);
};
export default PageButton;
Long story short; I have a button that involves a function and in that function I want to change the state (in this case a number) from another component that's taking the property from somewhere else.
So to me I made a stats component that takes in the value that I want to change and then the value is coming from the Table component and I want the button that I made that is coming from the Actions
component to change the state from the stats component. So instead of having the button in the Table Component (As seen below) I want to be able to run it from my Actions Component
Attached is the code that kinda works the way I want it but it doesn't look the way I want it (I want to invokve the change state function from the Actions column rather than inside the component where the state lives)
const Button = ({ handleClick, action, btnType }) => {
return (
<div>
<button class={btnType} onClick={handleClick}>
{action}
</button>
</div>
);
};
const Actions = ({ text, value, handleClick }) => {
return (
<td>
<button
type="button"
class="btn btn-primary"
data-toggle="modal"
id="exampleModal"
>
Launch demo modal
</button>
<Button btnType="btn btn-secondary" action="Attack" />{" "}
<Button btnType="btn btn-success" action="Travel" />{" "}
</td>
);
};
const Stats = ({ cash }) => {
return (
<td>
<ul>
<li>
{" "}
<span class="green">Cash: </span>
{cash}
</li>
<li>
<span class="red">HP: </span>100
</li>
<li>
<span class="blue">Energy: </span>100
</li>
</ul>
</td>
);
};
const Table = () => {
const [cash, setCash] = useState(300);
const sellAction = ({}) => {
setCash(cash - 1);
};
return (
<table>
<tr>
<th>Drugs</th>
<th>Quantity</th>
<th>Inventory</th>
<th>Stats</th>
<th>Actions</th>
</tr>
<TableItem />
<QuantItem />
<Inventory />
<Button
btnType="btn btn-danger"
handleClick={sellAction}
action="Sell"
/>{" "}
<Stats cash={cash} />
<Actions />
</table>
);
};
Pass setCash or sellAction function to Actions component as a prop. And then from Actions component, pass it to the Button component as a prop. Similar to what you did for cash.
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 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
I want to open the diaglog when the screen is visited so I set the default state to true. I made a custom button. When I click on it, the state should change to false and the dialog should close. However, the dialog doesnt close. What am I doing wrong and how else can I close the dialog?
<Dialog open={openReminder}>
<DialogTitle>Reminder</DialogTitle>
<DialogContent>
<DialogContentText>Don't forget to take your daily walk!</DialogContentText>
<div className={classes.reminderContainer}>
<DialogButton
text={"Ok, thanks!"}
onPress={() => setOpenReminder(false)}
/>
</div>
</DialogContent>
</Dialog>
export const DialogButton = ({ onPress, text }) => {
const classes = useStyles();
return (
<Button onPress={onPress} className={classes.button}>
{text}
</Button>
);
};
Issue is with the onPress event try using onClick,
<Button onClick={onPress} className={classes.button}>
{text}
</Button>
Two things which I note :
You need to change onPress to OnClick inside like this :
<Button onClick={onPress} className={classes.button}>
{text}
</Button>
Check inside your Dialog component that you explicitly hide it when 'open' prop is set to false.
<DialogButton text={"Ok, thanks!"} onPress={()=>setOpenReminder(!openReminder)}/>
<Button onClick={onPress} className={classes.button}>
{text}
</Button>
Change the onPress with onClick in your child component like this.
<Button onClick={onPress} className={classes.button}>
{text}
</Button>
check out if it works.