Get the button value from semantic ui react - reactjs

I am a newbie to React.Currently I am facing this problem.
Here is my code
handleClick(e) {
console.log('Click happened'+" "+ e.target.value);//getting UNDEFINED here
}
In the below code locationArr contains many locations
{ locationArr.map((location) => {
console.log(location); //It prints all the locations here NO PROBLEM
if (location !== ' ') {
return (
<div className ="ui stackable four column grid">
<div className="column centered">
</div>
<div className="column">
</div>
<div className="column centered">
<Button size='huge' primary value='{location}' as={Link}
to="/location" onClick={this.handleClick.bind(this)} >
{location} // ABLE TO GET LOCATION NAMES here
</Button>
Now my problem is I want to access the value of the location from the button in handleClick function and I also need to pass it to another component.Anyone please suggest me how do I achieve this?

Change
onClick={this.handleClick.bind(this)} to
onClick={this.handleClick.bind(location)}
Working Demo
Demo solves your both problems.

Related

How to disable second form if first one is clicked

I have two fields that show a modal when clicked on. I want to make one disabled if I select anyone first. I am using react-bootstrap for this project
<>
<div className='add-edit-product'>
<div className='d-flex align-items-center justify-content-center error-info mb-3'>
<img src={`../../../assets/img/about/${data.currencyHedge && data.marginFinancing ? "error-info-success.png" : "error-info.png"}`} className='me-3' />
{data.currencyHedge && data.marginFinancing ?
<p className='success'>Risks are acceptable due to mitigants</p> :
<p className='error'>The below risks require your attention</p>
}
</div>
<div className='form'>
<h2 className='mb-3'>Exchange rate risk</h2>
{data.currencyHedge && data.marginFinancing ? <p>No risk</p> :
<div>
{/*clicking on either of this tab will show a modal*/}
<div className='risk-tab' onClick={() => { setcurrencyHedgeModal(true); setSelected("currencyHedge") }}>
<h3>Enter a currency hedge</h3>
<img src={`../../../assets/img/about/${data.currencyHedge ? "correct-success.png" : "correct (1).png"}`} />
</div>
<div className='risk-tab' onClick={() => {setfinancingSufficientlyModal(true); setSelected("marginFinancing")}}>
<h3>Margin the financing sufficiently</h3>
<img src={`../../../assets/img/about/${data.marginFinancing ? "correct-success.png" : "correct (1).png"}`} />
</div>
</div>
}
</div>
</div>
<div className='footer_'>
<button onClick={() => hendelCancel()} className="footer_cancel_btn">cancel</button>
<button onClick={() => { nextStep() }} className='footer_next_btn'> Next</button>
</div>
{currencyHedgeModal && <CurrencyHedgeModal show={currencyHedgeModal} onHide={() => setcurrencyHedgeModal(false)} getModalData={(e) => modalGetData(e)} type={selected} />}
{financingSufficientlyModal && <FinancingSufficientlyModal show={financingSufficientlyModal} onHide={() => setfinancingSufficientlyModal(false)} getModalData={(e) => setData({ ...data, marginFinancing: e })} />}
</>
how can I add the logic to disable the next field if anyone is selected first. the image below is the form. (the green check mark shows when each form is filled and saved)
Question answer 1
Yes, if you want both inputs to trigger the opening of the modals you have to set onClick prop on both.
This depends on implementation and what do you specifically mean by disable an input. There are a couple of possible scenarios:
2.1 You may add a disabled class like so:
className={`${isOpened ? "disabled" : ""}`}
and then write some css.
2.2 You might rewrite onClick to just return when the modal is already opened instead of opening the second modal like so:
onClick={() => {
if (isOpened) return
setOpened(true)
}
P.S. You may need to add a second boolean flag to your state if you want this behaviour on both modals / inputs
Original answer
You have to use useState hook with a boolean flag isOpened
const [isOpened, setOpened] = useState(false)
Then update the state when clicking on yout input field
onClick={() => setOpened(true)}
Finally in your input fields you can use isOpened to disable them however you want, using styles or other logic.
P.S. Don't forget to call setOpened(false) when closig your modal

How do I pass a certain data onClick in React in this situation

Basically I have a loop that runs through "ScannedCrops" and each scannedcrop renders with a button which says "View More". I want to pass the id (Which is stored in ScannedCrop._id) and console.log that onClick.
This is the loop
<div className={styles.scannedCropsGrid}>
{
scannedCrops.map(ScannedCrop => {
return <div>
<div className={styles.center}>
<div className={styles.scannedCropsContent}>
<img src={ScannedCrop.image} alt="/" />
<div className={`${ScannedCrop.healthyBoolean ? styles.healthyPlant : styles.notHealthy}`}>
{
<p>{ScannedCrop.healthyBoolean ? "Healthy" : "Not Healthy"}</p>
}
</div>
<div className={styles.healthDesc}>
<p>{ScannedCrop.healthyBoolean ? "No Disease" : ScannedCrop.diseaseName}</p>
<p>||</p>
<p>{ScannedCrop.dateTime}</p>
</div>
<div className={styles.center}>
<button className={styles.viewMoreBtn}>
More Info
</button>
</div>
</div>
</div>
</div>
})
}
</div>
This is the onClick function in the same component.
const getId = () => {
}
What I want to do is that onClick I want to get the ScannedCrop._id and console.log it. I am kind of a beginner at this.
First of all you want to add a 'key' attribute to the parent in your map function. This can be either index or the ScannedCrop._id (if the later is always unique).
So it'll look like this:
...
{scannedCrops.map((ScannedCrop, index) => {
return <div key={index (or ScannedCrop._id if unique)} >
...
Lastly to answer your question, you first need to define your handler function and then pass it on to your button element inside the OnClick event. It should end up looking like this:
//it is a common practice to name your functions
//'handleClick', 'handleOnView' and so on. You can name it
//whatever you want
const handleGetId = (id) => console.log(id)
...
<div className={styles.center}>
<button
onClick={() => handleGetId(ScannedCrop._id)}
className={styles.viewMoreBtn}>
More Info
</button>
</div>
...
Hope that answers your question!

set first box clicked as a default at the first load

Im new in reactjs and I create a list of card by mapping in reactjs but I want my first card be clicked as a default at the first load what can i do for this code.
<div className="d-flex">
{data && data.length > 0
? data.map((item, index) => {
return (
<>
<div className="box-stock" onClick={() => selectData(item)}>
<div className="top-stock skewed p-5">
<h1>{item.symbol}</h1>
<strong className="text-center">
<span> (0.25)</span>
{item.stockNum}
</strong>
<Label className="text-center">
EPS:<span className="text-white">{item.EPS}</span>
</Label>
<Label className="text-center">
P/E:<span className="text-white">{item.PE}</span>
</Label>
</div>
</div>
</>
);
})
: 'no data'}
</div>
You can use useEffect hook to run program once it renders. Here, in useEffect pass empty array as a dependency so, that it runs only once.
useEffect(() => {
selectData(data[0])
}, [])
You can add click event on first load using javascript. The button will trigger the event on first load and you will get your first card clicked. Here is the code:
document.getElementsByClassName("box-stock").click()

React - Each child in a list should have a unique 'key' prop

As my first react project, I decided to try and make a Pokedex.
I have an array of Pokemon and that I pass into a List component and use the .map() function to render. I understand that the root-most element of that the .map() function returns needs a unique key and I understand that it is ideal if the key can be truly unique to the item so that if the list is sorted, items have the same key. Therefore, I figured using the 'id' of the pokemon would be ideal. I believe I have done that but I cannot get rid of the warning in console. I'd really appreciate a hand with this.
export default class List extends React.Component {
render() {
const { list, nav } = this.props;
return (
<div className="list">
{list.map((pokemon) => (
<PokemonItem key={pokemon.id} navigation={nav} pokemon={pokemon} />
))}
</div>
);
}
}
PokemonItem Render Method
render() {
const { pokemon, navigation } = this.props;
return (
<div onClick={() => {
navigation.navigate("Details", { pokemon });
}}
className={"list-item bg_" + pokemon.types[0]}>
<div className="header">
<div className="name">{pokemon.name}</div>
<div className="id">#{this.getId(pokemon.id)}</div>
</div>
<div className="body">
<div className="types">
{pokemon.types.map((type) => {
return <div className="type">{type}</div>;
})}
</div>
<div className="sprite">
<img src={pokemon.imgURL} alt={pokemon.name} title={pokemon.name}></img>
</div>
</div>
<div className="background-image">
<img src={PkBall} alt="" />
</div>
</div>
);
}
Warning message showing in console
Checking your PokemonItem it reveals that the reason may be laying in this piece of code:
{pokemon.types.map((type) => {
return <div className="type">{type}</div>;
})}
This is easily fixed by adding the key attribute:
{pokemon.types.map((type) => {
return <div className="type" key={type.id}>{type}</div>;
})}
You need to add a key in every item returned from a map in order to avoid this error. Also I advice you to add the console output related to your question in the body so it's easier to pinpoint the errors.
After the edit of the OP's question the warning occurs here:
<div className="types">
{pokemon.types.map((type) => {
return <div className="type">{type}</div>;
})}
</div>
The key-property is not set for div and should be done like in the first method. If type is unique you can use this as key.

How do you do a map within a map through an array for only certain items?

So far the map is working perfectly except for one problem, every time I click the button to post a comment a whole new post populates the UI. What I want is to only render a comment not a whole post every time I click the post comment button. What I tried to do is do map within a map, as you can see below. However its still rendering the a whole post. How do I map for a certain item, I think that will help. What should I do?
const { TextArea } = Input;
const PostOnWall = (props) => (
<div>
{props.postInfo.map( (item) => (
<div>
<div className="PostOnWall">
<div className="topbar">
<img src = {profile} className="image"/>
<div className="name">Brad Pitt</div>
<div>{item.time}</div>
</div>
<div className="text">{item.post}</div>
<img src={item.uploadedImage} />
</div>
<div className="engagementBar">
<div><FontAwesomeIcon icon={fathumbsup} size="2x"/> Like</div>
<div><FontAwesomeIcon icon={facomment} size="2x"/> Comment</div>
<div><FontAwesomeIcon icon={fasharesquare} size="2x"/> Share</div>
</div>
<div className="postCommentBox">
<img src = {profile} className="image"/>
<TextArea type = "text" placeholder="Write a comment" autoSize id="comment" onChange={props.onChange}/>
<div>
<button onClick={props.onClick}></button>
</div>
</div>
{item.comment.map( (items) => (
<div>
<div> {items} </div>
</div>
))
}
</div>
))
}
</div>
)
I think with current structure it's not really possible to re-render only comments. In order to make that possible you might need to move comments to a separate component.
Another important thing I spot you don't use key while rendering lists, so it decreases performance quite a lot as React will need to re-render the whole list on each render. You can read about it here: https://reactjs.org/docs/lists-and-keys.html

Resources