I have this piece of code, I want to show replies after the click event but it doesn't seem to fire or render.
// function for rendering comment's replies
const renderReplies = (comment) =>{
if(comment.data.replies){
return (
<div className="reply">
{comment.data.replies.data.children.map(reply => {
if(reply.data.body){
return (
<div className="comment-card">
<span className="comment-author">{reply.data.author}</span>
<ReactMarkdown>{reply.data.body}</ReactMarkdown>
<div className="upvotes">
<ImArrowUp id="comment-arrow-icon" />
{reply.data.score}
</div>
{showMoreReplies(reply)}
</div>
)
}
})}
</div>
)}}
const showMoreReplies = (reply) => {
if(reply.data.replies){
return (
<span className="show-all-replies" onClick={() => renderReplies(reply)} >Show more replies <HiArrowNarrowRight className="show-more-replies-arrow" /> </span>
)
}
}
If I execute renderReplies() within itself like this:
</div>
{renderReplies(reply)}
</div>
then the replies show up properly. The only issue is that I want them to show up after click event. I could use display: none but since I have a lot of comments with their own replies it will be a bit complicated
I have an array of objects, and for each one I .map it into a component called Card.js. Each card has an 'edit' button, and I have an edit form which I want to appear ONLY for the card on which I clicked the button.
At the moment, whatever I try to do to pass an id into the Editform.js component, it still makes the form appear for all of the card components.
Here's the current component I call which is meant to render just form for the clicked button. I pass in all of the cards in the 'cards' array, and what I believe is the id of the current .map object from the calling function:
function Editform({ cards, setCards, id }) {
const thisCard = cards.filter((card) => card.id === id)[0];
const editThisCard = thisCard.id === id; // trying to match id of passed card to correct card in 'cards' array.
console.log(editThisCard);
return (
<>
{editThisCard && ( // should only render if editThisCard is true.
<div className="form">
<p>Name of game:</p>
<input type="text" value={thisCard.gamename}></input>
<p>Max players: </p>
<input type="text" value={thisCard.maxplayers}></input>
<p>Free spaces: </p>
<input type="text" value={thisCard.freespaces}></input>
<p>Table #: </p>
<input type="text" value={thisCard.tablenum}></input>
<p></p>
<button type="button" className="playbutton">
Save changes
</button>
</div>
)}
</>
);
}
export default Editform;
edit: apologies, I forgot to paste in the other code. Here it is. Note that I'm just hardcoding in a couple of cards for now:
import React from "react";
import ReactFitText from "react-fittext";
import Editform from "./Editform";
function Displaycards({ lastid }) {
const [cards, setCards] = React.useState([
{
id: 1,
gamename: "El Dorado",
maxplayers: 4,
freespaces: 1,
tablenum: 5,
},
{
id: 2,
gamename: "Ticket to Ride",
maxplayers: 4,
freespaces: 2,
tablenum: 3,
},
]); // using the React state for the cards array
const [showForm, setShowForm] = React.useState((false);
return (
<div className="cardwrapper">
{cards.map(({ id, gamename, maxplayers, freespaces, tablenum }) => {
return (
<div key={id}>
<div>
<div className="card">
<ReactFitText compressor={0.8}>
<div className="gamename">{gamename}</div>
</ReactFitText>
<div className="details">
<p>Setup for: </p>
<p className="bignumbers">{maxplayers}</p>
</div>
<div className="details">
<p>Spaces free:</p>
<p className="bignumbers">{freespaces}</p>
</div>
<div className="details">
<p>Table #</p>
<p className="bignumbers">{tablenum}</p>
</div>
<button type="button" className="playbutton">
I want to play
</button>
<br />
</div>
<div className="editbuttons">
<button
type="button"
className="editbutton"
onClick={() => setShowForm(!showForm)}
>
Edit
</button>
<button type="button" className="delbutton">
X
</button>
</div>
{showForm && (
<div>
<Editform
cards={cards}
setCards={setCards}
id={id}
/>
</div>
)}
</div>
</div>
);
})}
</div>
);
}
export default Displaycards;
I feel like I'm missing something obvious, but I can't get my head around what it is. The current iteration of it is here - https://github.com/TSDAdam/lfp/tree/usestate-trial - and it was created with create-react-app .
It sounds like you have one state controlling all of the Cards. You haven't shown the Card component yet however. Have every Card control its own state, so when the edit button bound to the card is clicked, it only applies to that one card. If you show us more code we can narrow it down, but this is most likely the gist of your problem.
The problem is that the EditForm is inside the map function, so for every item in your cards array, a separate EditForm is rendered with the corresponding values, and all these EditForms get shown/hidden based on the same boolean in your state.
The solution is to move the EditForm outside the map function, and create a new state object that tracks an "active" card, from where the single EditForm could take its values.
This of course won't work if you want to render the EditForm in a position relative to the "active" card.
[Edit]
Okay, I ended my answer with a caveat, but I should add a solution for that as well, since it isn't very complicated.
If you want to render an EditForm below the selected card, for example, the approach would be to keep it inside the map function as it is now, and change the boolean state variable showForm into one that accepts a string/number (depending on what you use as the identifier for each card). And then use this state variable to determine which form shows at any given time.
const [showForm, setShowForm] = React.useState("");
{cards.map(({ id, gamename, maxplayers, freespaces, tablenum }) => {
return (
<div key={id}>
// Rest of the JSX
<div className="editbuttons">
<button
type="button"
className="editbutton"
onClick={() => setShowForm(id)}
>
Edit
</button>
<button type="button" className="delbutton">
X
</button>
</div>
{showForm == id && (
<div>
<Editform
cards={cards}
setCards={setCards}
id={id}
/>
</div>
)}
</div>
</div>
);
})}
I have card mapped with data from an "json" file and want the same details on the card to display on the modal menu
In the code snippet is the code for the cards that are displayed and the modal the modal works properly (opens and closes) but I now want to use the data from the cards in the modal but it doesn't show. I used the card key to specify which cards data to use but don't think that it works this way. I am new to react and think I need to use props but can't find any material that can explain it in a way I understand. Please help if you can any critsism will be gladly accepted and any other ways to improve my code will also help. Any learning material will also be hugely helpful.
Code:
{
details.map((details) => {
return (
<div className="card" key={details.id}>
<img src={details.image} alt="" />
<h5 className="board-name">{details.design}</h5>
<p className="board-size">Size: {details.size}</p>
<h6 className="board-price">{details.price}</h6>
<button className="add-to-cart" onClick={() =>
setModalDisplay(true)}> click me
</button>
</div>
)
})
}
{modalDisplay &&
<div className="backdrop">
<div className="cart-card" key={details.id}>
<div className="item-details">
<img src={details.image} alt="" width="98px" height="98px" />
<h4 className="item-name">{details.design}</h4>
<p className="item-size">{details.size}</p>
<h6 className="item-price">{details.price}</h6>
<button className="exit-modal" onClick={() =>
setModalDisplay(false)}>
</button>
</div>
<span className="modal-inputs">
<button className="minus-btn">-</button>
<input type="text" className="amount-input" value="01" />
<button className="plus-btn">+</button>
<button className="add-btn">Add to cart</button>
</span>
</div>
</div>
}
</div>
You could store the card data in an onClick that sets it in an state for example and use the state in the modal as props or directly. I think that would be the best option to use in this case.
I am creating a clone of the Netflix web app. I am currently developing the landing page. I have included my code below. This is one of the few different ways I have attempted structuring this page.
The layout currently is appearing how I want it to look, however the "main-slice__language-button" and the "main-slice__signin-button" at the top of the page are not working – meaning nothing happens when I click the select dropdown, and the Sign In button is not appearing as clickable. Can anyone explain why it does not work this way and any suggestions for better alternatives?
screenshot of landing page
import backgroundImage from '../../images/mooshflix-background.jpeg';
import netflixLogo from '../../images/netflix-logo.png';
import './MainSlice.css';
const MainSlice = () => {
return (
<div className='main-slice-container'>
<img className='background-image' src={backgroundImage} alt='mooshflix background' />
<div className='header'>
<img className='main-slice__logo' src={netflixLogo} alt='' />
<div className='main-slice__header-buttons'>
<select className='main-slice__language-button'>
<option>English</option>
<option>Spanish</option>
</select>
<button className='main-slice__signin-button'>Sign In</button>
</div>
</div>
<div className='main-slice__text-container'>
<h1 className='main-slice__title'>Unlimited movies, TV shows, and more.</h1>
<h2 className='main-slice__subtitle'>Watch anywhere. Cancel anytime.</h2>
<div className='main-slice__email-form-container'>
<h3 className='email-form-title'>Ready to watch? Enter your email to create or restart your membership.</h3>
<form>
<input placeholder='Email Address' ></input>
<button className='main-slice__email-form-button'>Get Started ></button>
</form>
</div>
</div>
</div>
)
}
export default MainSlice;```
because you DID NOT do anything, what event did u call for that button? you have to add some event listeners like onClick to your btn, like below:
const onStart = () => {
DO STH WHAT YOU WANT
}
<button className='main-slice__email-form-button' onClick={onStart}>
Get Started
</button>
I want to add button to my form to dynamically add inputs. Yet I found that, if i added a button to my form that simply logs to the console, (and when I try to add inputs) it logs and then the form breaks. The front end window of my Electron app crashes (doesn't exit but turns grey) and automatically restarts on the same page without the dialog open that contains the form.
Here is a snippet of my form code:
TaskCreation.js
return (
<div className="modal-body">
{values.products.map((product, i) => {
return(
<div key={i}>
<Form.Row>
<Form.Group as={Col} controlId={"keywords-" + i}>
<Form.Label>Keywords (e.g. '+box +logo +tee')</Form.Label>
<Form.Control
value={product.keywords.join(' ')}
onChange={handleChange}
>
</Form.Control>
</Form.Group>
</Form.Row>
...
<div style={{ marginTop:'10px' }}>
<button onClick={() => console.log(123)}>Add Product</button> // this breaks when clicked
</div>
...
);
Any help is welcome, let me know what other information I should provide.
I think that the button activates the 'submit' from form. So, you can try somethings. Add the atribute type="button" to your button, and/or use ".preventDefault()".
const handleButton = (event) => {
event.preventDefault()
console.log(123)
}
<div style={{ marginTop:'10px' }}>
<button type="button" onClick={handleButton}>Add Product</button>
</div>