tell me how to click on the 'Next' button to activate the class of the element. When clicking on a certain class, styles should change. How to correctly implement this example in this function?
export default ({ title, img, onNext }) => {
return (
<div>
<div className={cn('info')}>
<Button shape="round">Start</Button>
<Button shape="round" type="default" onClick={onNext}> Next</Button>
</div>
</div>
);
};
Create a function to do click operation
import React, { useState } from 'react';
const MyComponent = ({ title, img, onNext }) => {
const [active, setActive] = useState(false);
const onNext = () => {
setActive(true);
}
return (
<div>
<div className={cn('info')} style={active ? {backgroundColor: '#ff0000'} : null}>
<Button shape="round">Start</Button>
<Button shape="round" type="default" onClick={onNext}>
Next
</Button>
</div>
</div>
);
}
export default MyComponent;
Same as you can also change className dynamically
Related
For example I have this code.
And I want to use CSS transitionfor Button when showButton and when !showButton. Now it's just removed and add Button when showButton changes.
{showButton && (
<Button
onClick={() => setShowMessage(true)}
size="lg"
>
Show Message
</Button>
)}
Is it possible make by some events or appending classNames like active?
Append the className with the ternary operator.
But, for example, this code will only adjust the class of the button specified (effectively doing the same thing you described, hiding & showing the button):
import React, { useState } from 'react';
export const Component = () => {
const [showButton, setShowButton] = useState(false);
const handleClick = () => {
setShowButton(true);
}
return (
<button
onClick={handleClick}
className={showButton ? 'showButtonClass' : 'hideButtonClass'}
>
Show Message
</button>
);
};
For content to show once the button is clicked, you'll need something like:
import React, { useState } from 'react';
export const Component = () => {
const [showMessage, setShowMessage] = useState(false);
const handleClick = () => {
setShowMessage(true);
}
return (
<div>
<button
onClick={handleClick}
>
Show Message
</button>
{showMessage && <h1>
The message you'll see when clicking!
</h1>}
</div>
);
};
import React, { useState, useEffect } from 'react'
import { Link } from 'react-router-dom'
import moment from 'moment'
import Avatar from '../../components/Avatar/Avatar'
import { useSelector, useDispatch} from 'react-redux'
import { useParams } from 'react-router-dom'
import { deleteAnswer } from '../../actions/question'
const DisplayAnswer = ( { question, handleShare } ) => {
const User = useSelector((state) => (state.currentUserReducer))
const dispatch = useDispatch()
const { id } = useParams()
const [button, setButton] = useState(false);
const handleDelete = (answerId, noOfAnswers) => {
dispatch(deleteAnswer(id, answerId, noOfAnswers-1))
}
const handleComment = (e) => {
setButton(!button)
alert(e.target.id)
}
return (
<div>
{
question.answer.map( (ans) => (
<div className="display-ans" key={ans._id}>
<p>{ans.answerBody}</p>
<div className="question-actions-user">
<div>
<button type="button" onClick={handleShare}>Share</button>
{
User?.result?._id === ans?.userId && (
<button type='button' onClick={ () => handleDelete(ans._id, question.noOfAnswers) }>Delete</button>
)
}
<div>
</div>
<button id = {ans._id} type='button' onClick = { (e) => handleComment(e) }> Add Comment </button>
{
button &&
(
<div id = {ans._id}>
<textarea rows='5' cols='30'> </textarea> <br />
<button type='button'> Post </button>
</div>
)
}
</div>
<div>
<p>answered { moment(ans.answeredOn).fromNow()}</p>
<Link to={`/Users/${ans.userId}`} className='user-link' style={{color:'#0086d8'}}>
<Avatar backgroundColor="lightgreen" px='8px' py='5px' borderRadius='4px'>{ans.userAnswered.charAt(0).toUpperCase()}</Avatar>
<div>
{ans.userAnswered}
</div>
</Link>
</div>
</div>
</div>
))
}
</div>
)
}
export default DisplayAnswer
I want to add a comment part under every answer
to do that i added a " Add Comment " button under every Answer and i have a button click on that button
and what i want is whenever the button is clicked the addcomment (textbox) should be added under it
but when i click the button the addcomment (textbox) is getting added under every answer
like if 10 answers are their then Addcommment box is getting added under every 10 answers
Currently there is only a single button state that all the mapped answers render a button for. A simple solution would be to instead store the answer id of the answer you want to add a comment for.
Example:
const DisplayAnswer = ({ question, handleShare }) => {
...
const [commentId, setCommentId] = useState(null); // <-- initially null
...
const handleComment = (e) => {
setCommentId(e.target.id); // <-- set answer id here
alert(e.target.id);
};
return (
<div>
{question.answer.map((ans) => (
<div className="display-ans" key={ans._id}>
<p>{ans.answerBody}</p>
<div className="question-actions-user">
<div>
...
<button
id={ans._id}
type="button"
onClick={handleComment}
>
Add Comment
</button>
{commentId === and._id && ( // <-- conditionally render match by id
<div id={ans._id}>
<textarea rows="5" cols="30" />
<br />
<button type="button">Post</button>
</div>
)}
</div>
...
</div>
</div>
))}
</div>
);
};
When the "Post comment" button is clicked and the entered comment is handled don't forget to also set the commentId value back to null to conditionally hide the input.
Each answer must have his own 'state' to display his own textArea, so you have to extract the code of the 'answer' in a new Answer component, and render a new component in the map method.
Each Answer will thus use a "useState" with a "[isTextAreaVisible, setIsTextAreaVisible] = useState(false);" state.
This is a very noob question but I've been trying all day do implement this. Please help me out.
Sorry for the length, just tried to put out the whole thing I am struggling with
I am trying to build custom buttons and to do so, I created a component so I can create as many buttons that I want. For that I declared a state and passed down some information as props, which is as follows:
import React, {useState} from 'react'
import Button from '../components/Button'
function CustomButton() {
const [clicked, setClicked] = useState(false)
return (
<div className='CustomButton'>
<Navbar />
<Button setClicked={setClicked} name="Button One" clicked={clicked}/>
<Button setClicked={setClicked} name="Button Two" clicked={clicked}/>
<Button setClicked={setClicked} name="Button Three" clicked={clicked}/>
</div>
)
}
export default CustomButton
As you can see, we passed the state and name of that button down. To render this Buttons, following component has been created:
import React from 'react'
import Modal from './Modal/Modal'
function Button({setClicked, name, clicked}) {
return (
<div>
<button onClick={() => {setClicked(true)}}>{name}</button>
{clicked && <Modal closeModal={setClicked} name={`You Clicked ${name}`} />}
</div>
)
}
export default Button
And lastly, when once a button is clicked, we want to perform some action. That action is to pop the Modal on a screen. And to do so, we created a Modal and passed down few props. Code for the same is as follows:
import React from 'react'
function Modal({closeModal, name}) {
return (
<div className='modal'>
<div className='modalContainer'>
<p>{name}</p>
<div>
<button onClick={() => {closeModal(false)}}>×</button>
</div>
</div>
</div>
)
}
export default Modal
The expected result is for a Modal to pop with "You clicked button One", supposing we clicked one something similar to this.
The actual result is that all three Modals pop up one above the other when any of the three buttons are passed. The result:
I realize that I am passing the states wrong way. When any of the button is clicked all three get set to true. I simply don't realize how. Don't they create a method for each one?
Also, can you guys please teach me a better/understandable way to write clicked logic. Like maybe
if(clicked){
<Modal closeModal={setClicked} name={`You Clicked ${name}`} />
}
Because you bind all three buttons with one state, You need a state as array, with items equal to the number of buttons.
const [clicked, setClicked] = useState([false, false, false])
return (
<div className='CustomButton'>
<Navbar />
{
clicked.map((button, i) => {
return <Button setClicked={setClicked} name="Button Three" clicked={clicked[i]} index={i}/>
})
}
</div>
)
Then in the button component.
function Button({setClicked, name, clicked, index}) {
return (
<div>
<button onClick={() => {setClicked(prev => prev.map((item, i) => {
return i === index ? true : item
}))}}>{name}</button>
{clicked && <Modal closeModal={setClicked} name={`You Clicked ${name}`} />}
</div>
)
}
And the modal component.
function Modal({ closeModal, name, index }) {
return (
<div className="modal">
<div className="modalContainer">
<p>{name}</p>
<div>
<button
onClick={() => {
closeModal((prev) =>
prev.map((item, i) => {
return i === index ? false : item;
})
);
}}
>
×
</button>
</div>
</div>
</div>
);
}
You can find a working example on this link.
https://codesandbox.io/s/old-wood-zgjno9
You can implement multiple modals like this:
import { useState } from "react";
export default function App() {
const [showModal1, setShowModal1] = useState(false);
const [showModal2, setShowModal2] = useState(false);
return (
<div className="App">
<button onClick={(e) => setShowModal1(true)}>Button 1</button>
<button onClick={(e) => setShowModal2(true)}>Button 2</button>
{showModal1 && (
<Modal text="Modal 1" onClose={(e) => setShowModal1(false)} />
)}
{showModal2 && (
<Modal text="Modal 2" onClose={(e) => setShowModal2(false)} />
)}
</div>
);
}
const Modal = ({ text, onClose }) => {
return (
<div>
{text}
<button onClick={onClose}>Close</button>
</div>
);
};
Working example
I have a small React app that makes calls to a JSON file and returns the text of a card.
I have successfully made this work by calling the onClick on a button, but what I really want to do is add a onClick as an event to my Cards module I've created. I've looked at binding at this level but with no success;
<Cards name={card} onClick={() => setCard(Math.floor(Math.random() * 57) + 1)}/>
Do I need to write a custom handler in my cards.js to handle the onClick? Or can I append it within this file (App.js)?
The full code is below.
import React, { useState } from 'react';
import './App.css';
import Cards from '../cards';
function App() {
const [card, setCard] = useState('1');
return (
<div className="wrapper">
<h1>Card text:</h1>
<button onClick={() => setCard(Math.floor(Math.random() * 57) + 1)}>Nile</button>
<Cards name={card} />
</div>
);
}
export default App;
My card.js component code is;
export default function Cards({ name }) {
const [cardInformation, setCards] = useState({});
useEffect(() => {
getCards(name)
.then(data =>
setCards(data)
);
}, [name])
const FlippyOnHover = ({ flipDirection = 'vertical' }) => (
<Flippy flipOnHover={true} flipDirection={flipDirection}>
</Flippy>
);
return(
<div>
<Flippy flipOnHover={false} flipOnClick={true} flipDirection="vertical" style={{ width: '200px', height: '200px' }} >
<FrontSide style={{backgroundColor: '#41669d',}}>
</FrontSide>
<BackSide style={{ backgroundColor: '#175852'}}>
{cardInformation.continent}
</BackSide>
</Flippy>
<h2>Card text</h2>
<ul>
<li>{cardInformation.continent}</li>
</ul>
</div>
)
}
Cards.propTypes = {
name: PropTypes.string.isRequired
}
We can create an event. So let's call it onSetCard.
App.js file:
class App extends Component {
handleSetCard= () => {
// set state of card here
};
<Cards name={card}
card=card
onSetCard={this.handleSetCard}
/>
}
Cards.js file:
class Cards extends Component {
render() {
console.log("Cards props", this.props);
return (
<button
onClick={() => this.props.onSetCard(this.props.card)}
className="btn btn-secondary btn-sm m-2"
>
FooButton
</button>
)
}
}
I'm trying to pass data into Modal (bootstrap) popup and display some data.
I have a list of orders with a button 'display info', and every button that i press should display on the popup (Modal) diffrent data.
My question is how should i pass the data to the Modal?
this line <Button variant="primary" onClick={() => {this.handleModal(index)}}> Items info</Button> should trigger the Modal. In the handleModal function it passes the order index. And then i update the index on the setState of the handleModal function.
The Modal open but nothing passes to it.
I'm not sure that this is the correct way of doing it.
Also the Modal is inside the loop of the filteredOrders, should i move the Modal outside the loop?
And if yes, how should i do that and where?
import React, {useState} from 'react';
import './App.scss';
import {createApiClient, Item, Order} from './api';
import Modal from 'react-bootstrap/Modal';
import Button from 'react-bootstrap/Button';
import 'bootstrap/dist/css/bootstrap.min.css'
export type AppState = {
orders?: Order[],
search: string;
show:boolean;
item?: Item,
order_id: number,
}
const api = createApiClient();
export class App extends React.PureComponent<{}, AppState> {
state: AppState = {
search: '',
show:false,
order_id: 0,
};
searchDebounce: any = null;
async componentDidMount() {
this.setState({
orders: await api.getOrders()
});
}
async getItem(itemID: string){
this.setState({
item: await api.getItem(itemID)
});
}
render() {
const {orders} = this.state;
return (
<main>
<h1>Orders</h1>
<header>
<input type="search" placeholder="Search" onChange={(e) => this.onSearch(e.target.value)}/>
</header>
{orders ? <div className='results'>Showing {orders.length} results</div> : null}
{orders ? this.renderOrders(orders) : <h2>Loading...</h2>}
</main>
)
}
handleModal(index: number)
{
this.setState({
show:true,
order_id: index,
})
}
handleClose () {
this.setState({show: false})
}
renderOrders = (orders: Order[]) => {
const filteredOrders = orders
.filter((order) => (order.customer.name.toLowerCase() + order.id).includes(this.state.search.toLowerCase()));
const requiredItem = this.state.order_id;
const modelData = filteredOrders[requiredItem];
return (
<div className='orders'>
{filteredOrders.map((order,index) => (
<div className={'orderCard'}>
<div className={'generalData'}>
<h6>{order.id}</h6>
<h4>{order.customer.name}</h4>
<h5>Order Placed: {new Date(order.createdDate).toLocaleDateString()}</h5>
</div>
<div className={'fulfillmentData'}>
<h4>{order.itemQuantity} Items</h4>
<img src={App.getAssetByStatus(order.fulfillmentStatus)}/>
{order.fulfillmentStatus !== 'canceled' &&
<a href="#" onClick={() => this.ChangeStatus(order)}>Mark
as {order.fulfillmentStatus === 'fulfilled' ? 'Not Delivered' : 'Delivered'}</a>
}
</div>
<div className={'extraData'}>
<Button variant="primary" onClick={() => {this.handleModal(index)}}> Items info</Button>
<Modal show={this.state.show} >
{/*{console.log(modelData)}*/}
{/*<Modal.Header closeButton>*/}
{/* <Modal.Title>Item Info</Modal.Title>*/}
{/*</Modal.Header>*/}
<Modal.Body>
{ console.log(modaelData) }
</Modal.Body>
<Modal.Footer>
<Button onClick={() =>{ this.handleClose()}}>
Close
</Button>
</Modal.Footer>
</Modal>
</div>
<div className={'paymentData'}>
<h4>{order.price.formattedTotalPrice}</h4>
<img src={App.getAssetByStatus(order.billingInfo.status)}/>
</div>
</div>
))}
</div>
)
};
}
export default App;
I don't think you need to pass data to the Modal, but rather compose the Modal with the data in the first place. It is currently empty. Then you can continue to hide/show the complete Modal with handleModal.