Display a specific component by its key - reactjs

I have this WP API data that I'm fetching in to a component called "HostingCard". I am mapping through this component which renders three cards. While mapping through these I am assigning a key to each of them.
`{hostings.map((hosting) => (
<HostingCard key={hosting.id} hosting={hosting} setHosting={setHostings} />
))}`
Each card has one of these titles "Pro", "Standard" and "Basic".
I made it so that once a card is clicked a new component appears. This component is called "ContactFormular".
Now in the "ContactFormular" component I want to display the information that was on the card that was clicked. is this possible?
Here's the code that opens a new component once the card/button is clicked:
import ContactFormular from './ContactFormular'
const HostingCard = ({post, handleSubmit, hosting, setHosting, showContactDialog, setShowContactDialog, ssl, setPro, pro, key}) => {
return (
<div className='noselect hosting-options'>
<input type="radio" id={post.acf.hosting} name="startup" />
<div className='card selected-card'>
<form onSubmit={handleSubmit}>
<label for={post.acf.tilvalg} className='label'>
<div className='card-header'>
<h5>{hosting.acf.title}</h5>
<p>{hosting.acf.beskrivelse}</p>
</div>
<div className='pakke-detaljer'>
<div>
<p style={{display: hosting.acf.deltaljer ? 'block' : 'none'}}>{hosting.acf.deltaljer}</p>
</div>
</div>
<div className='button-header' onClick={() => setPro(false)}>
<button className='btn' onClick={() => setShowContactDialog(true)}>Vælg</button>
</div>
</label>
</form>
</div>
<ContactFormular key={hosting.id} post={post} hosting={hosting} setHosting={setHosting} showContact={showContactDialog} setShowContact={setShowContactDialog} handleSubmit={handleSubmit} ssl={ssl} pro={pro} setPro={setPro}/>
</div>
)
}

It looks like you're passing in showContactDialog as a parameter and using that to decide whether or not to show this new component right? That means you need showContactDialog to be true for only the one you clicked on, and false for the others. ie each component needs a different state variable. It looks like you might be sharing the same state variable between all components. It's impossible to tell unless you share a reproducible example

Related

Pass component input value to the same component in a different class

I have a SearchBarComponent that looks like this
const SearchBarComponent = ({inputStyle, searchIconSize, onChange, formClass, query, name, onClick, formContainerClass}) => {
return (
<div className={formContainerClass}>
<form className={formClass}>
<div class="form-group">
<input type="text" value={query} onChange={onChange} name={name} class="form-control shadow-none" placeholder="Search your dream car.." style={inputStyle}/>
<Link to="/car-list">
<BiSearchAlt2 onClick={onClick} className="search-icon" size={searchIconSize}/>
</Link>
</div>
</form>
</div>
)
};
export default SearchBarComponent;
I have a landing screen with the SearchBarComponent where a user can enter a search query, when they click it, it should populate the SearchBarComponent in the results page (Which is in a different component) so that it moves the props to the other SearchBarComponent and displays the results.
I don't know if it makes sense but here's a small snippet of what I'm looking for but struggling to implement.
https://codesandbox.io/s/epic-bhabha-p5htt4?file=/src/App.js

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()

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

Navigate with tabIndex when elements where hidden

Summary
I want to understand how the tabulation navigation works on browser, in order to perform custom input with suggestion field on React.
Objective
The objective is to provide 2 custom input to the use with suggestion dropdown. When I click to my input, the dropdown shows correctly and I can navigate through the tabulation key to my suggestions. But when I try to navigate to the next input, the dropdown shows but I can't navigate through my second dropdown suggestion.
Code example
I have the following JSX code:
class InputDropdown React.Component {
render() {
return(<div>
<div id="input1" className="input-wrapper" onMouseEnter={...} onMouseLeave={...} onBlur={...}>
<input className={"input"}
value={this.state.search_input}
onKeyDown={(e) => e.keyCode==13?this.props.validate(this.state.search_input)}
onFocus={this.setState(display_dropdown_input1: true)}
/>
<div className={"dropdown-wrapper" + this.state.display_dropdown_input1?"":"hidden"}>
{this.props.suggestion.map((suggestion, index) =>
<div className="suggestion"
tabIndex={0}
onKeyDown={(e) => e.keyCode==13?this.props.validate(suggestion.text)}
onBlur={index+1==this.props.suggestion.length?this.setState({display_dropdown_input1:false})}
>{suggestion.text}</div>)}
</div>
</div>
<div id="input2" className="input-wrapper" onMouseEnter={...} onMouseLeave={...} onBlur={...}>
<input className={"input"}
value={this.state.search_input}
onKeyDown={(e) => e.keyCode==13?this.props.validate(this.state.search_input)}
onFocus={this.setState(display_dropdown_input2: true)}
/>
<div className={"dropdown-wrapper" + this.state.display_dropdown_input2?"":"hidden"}>
{this.props.suggestion.map((suggestion, index) =>
<div className="suggestion"
tabIndex={0}
onKeyDown={(e) => e.keyCode==13?this.props.validate(suggestion.text)}
onBlur={index+1==this.props.suggestion.length?this.setState({display_dropdown_input2:false})}
>{suggestion.text}</div>)}
</div>
</div>
</div>)
}
}
Question
It's as if the tabulation navigations road is prepared on the first tabulation pressed and if element appear after this press they are not taken in count.
Is it possible to perform it in React?

React returns my mapped-over array data out of order

In my main component App.js, I have an array of data received from a redux store that looks like this:
[
{...}, {...}
]
Each object in the array contains information about a post (like a reddit post) that I map over to display as a preview card. Upon clicking that preview card, a modal card will display with a detailed view of the post.
// From App.js:
return (
<div className="entirePostList">
<NavBar />
<div className="postListContainer">
<div className="postListRow">
{posts.map((post) => (
<div key={post.id} onClick={this.openDetailsPostModal}>
<PostCard post={post} />
</div>
))}
</div>
</div>
<button className="newPostButton"
onClick={this.openCreatePostModal}>
<MdAddCircle />
</button>
<Modal // VIEW POST DETAILS MODAL
className='modal'
overlayClassName='createOverlay'
isOpen={detailsPostModalOpen}
onRequestClose={this.closeDetailsPostModal}
contentLabel='Modal'
>
<div>
{loadingDetailsPost === true
? <div>
<div className="postEditorBg" />
<Loading type='bubbles'
delay={200}
color='#fed80a'
className="loading"
width={120} />
</div>
: <div>
<div className="postEditorBg" />
<PostCardDetails />
</div>
}
</div>
</Modal>
In the <PostCardDetails /> component, I am receiving the same array of data from the redux store and mapping over it in the same way to display the data as UI. It displays correctly, but the problem is when I click a card preview, it displays the wrong detailed card (not the one you would expect based on the preview).
Here's the github repo in case more context is needed.
I'm beyond stuck on this - person who can answer this shall receive love and respect for eternity.

Resources