I did some research but also I didn't find a proper answer
import Card from "./components/Card/card";
class CardCollection extends Component {
render() {
return (
<div>
<Card />
<Card />
<Card />
</div>
);
}
}
export default CardCollection;
How do I style** those Card components?
I tried:
<div className="class-name1"> <Card /> </div>
<div className="class-name2"> <Card /> </div>
<div className="class-name3"> <Card /> </div>
But I think it's not the good way to do it.
Neither this
<Card propName="margin-tb-20" />
<Card propName="margin-tb-20" />
<Card propName="margin-tb-20" />
<Card propName="margin-tb-20" />
<Card propName="margin-tb-20" />
Even doing this by using the loop does not look good for me. So is there any alternative?
First of all, you must provide component name capitalized:
cardCollection // Rename it to CardCollection
Now, to your query; you can provide props to the component:
<Card className="class-name1" />
And in the Card component, you can provide the props:
{/* card */}
<div {...props}>
eways to do it:
1- via passing inline style:
a: <Card style={{color:"red"}} />
b: inside of card comp you can use it like:
<div style={this.props.style}>
2- by class name:
a: <Card cssClassName="c1" />
b: use it on every element inside of card like example:
<div className={this.props.cssClasName}>
note that if Card comp is a component that you import from a library you should read it's document instead, normally they implemented both ways
Related
I'm new to react. I want to receive props from NavItemsLayout but I don't know how
const NavItemsLayout = (props)=>{
return(
<div className="nav-items">
Hellow World
</div>
)
}
const Navbar = ()=>{
return(
<div className="navbar">
<AppLayout
NavLayoutComponent={NavItemsLayout} // How to receive props from NavItemsLayout
/>
</div>
)
}
you can simply use arrow function to do it
sth like this :
<div className="navbar">
<AppLayout
NavLayoutComponent={(props)=> <NavItemsLayout {...props} foo={'bar'} />}
/>
</div>
or use react without jsx
like this :
<div className="navbar">
<AppLayout
NavLayoutComponent={(props)=> React.createElement(NavItemsLayout , {...props,foo: 'bar'}, null)}
/>
</div>
My goal is to use an onClick function in one of my components, and pass that data to another component (end goal is that in the other component called Playlist, it updates an array with the id of the clicked item).
I am just not sure how to pass the information between child components
My main component (app.jsx) looks like this
const mainCards = Data.map(card => {
return(
<MainCard
key={card.id}
id={card.id}
image={card.url}
title={card.title}
playbutton={card.playbutton}
addbutton={card.addbutton}
/>
)
})
const sideCards = SideData.map(card => {
return(
<SideCard
image={card.sideurl}
key={card.id}
title={card.sidetitle}
playbutton={card.playbutton}
addbutton={card.addbutton}
/>
)
})
return (
<div className="App">
<Navbar />
<Header />
<Playlist />
<CardContainer />
<div className="maincards">
{mainCards}
</div>
<div className="sidecards">
{sideCards}
</div>
</div>
)
}
export default App
The component where I am using onClick (MainCard.jsx)
const handleAdd = (id) => {
console.log(id)
}
return(
<div className="mainCardObject">
<div className="cardObj">
<img src={props.image} className ="mainCardImage"/>
<img src={props.playbutton} className="playbutton"/>
<img src={props.addbutton} onClick={() => handleAdd(props.id)} className="addbutton" />
</div>
</div>
)
}
export default MainCard
and the component I wish to pass information to (nothing inside, as I dont know where to start)
return(
<div className="playlistContainer">
<ul>
<li></li>
</ul>
</div>
)
}
export default Playlist```
My suggestion is that you manage 'ids array' state globally creating a context, using the hook useContext(). Here a link with a simple explanation. I hope it helps!
https://www.w3schools.com/react/react_usecontext.asp
This question already has answers here:
Warning: Function components cannot be given refs
(7 answers)
Closed 8 months ago.
I have a HeaderIcon component that looks like this:
function HeaderIcon({ inactiveIcon, activeIcon }) {
const [isActive, setIsActive] = useState(false);
return (
<div onClick={() => setIsActive(!isActive)}>
{isActive ? activeIcon : inactiveIcon}
</div>
);
}
export default HeaderIcon;
When I run my code I got these errors:
Unhandled Runtime Error
Error: Hydration failed because the initial UI does not match what was rendered on the server.
Error: There was an error while hydrating. Because the error happened outside of a Suspense boundary, the entire root will switch to client rendering.
And I checked my console and saw this:
Warning: Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?
This is where I used my HeaderIcon:
function Header() {
return (
<IconContext.Provider value={{ size: "30", color: "#374957" }}>
<header className="flex items-center justify-around py-1.5 px-3 bg-white">
<div className="flex items-center space-x-2 w-full max-w-xs">
<h1 className="text-4xl">Zipp</h1>
</div>
<div className="py-2.5 px-4 flex items-center">
<InputGroup>
<InputLeftElement
pointerEvents="none"
children={<SearchIcon color="grey" />}
/>
<Input
type="text"
bg="whitesmoke"
w={"full"}
focusBorderColor="none"
border={"none"}
placeholder="Search"
/>
</InputGroup>
</div>
{/* right */}
<div className="flex items-center space-x-6">
<div className="headerIcons active:opacity-80">
<Link href="/">
<HeaderIcon
inactiveIcon={<AiOutlineHome />}
activeIcon={<AiFillHome />}
/>
</Link>
</div>
<div className="headerIcons">
<HeaderIcon
inactiveIcon={<MdOutlineAddBox />}
activeIcon={<MdAddBox />}
/>
</div>
<div className="headerIcons -rotate-12">
<HeaderIcon
inactiveIcon={<AiOutlineNotification />}
activeIcon={<AiFillNotification />}
/>
</div>
<div className="cursor-pointer">
<Avatar w={7} h={7} />
</div>
</div>
</header>
</IconContext.Provider>
);
}
Since you are adding a Functional Component inside Next.js's Link tag, there are some changes to be made. Here is an overview of what the say in the documentation:
If the child of Link is a functional component, in addition to using passHref, you must wrap the component in React.forwardRef.
Which means, first you should add passHref prop to Link when using HeaderIcon, this way:
<Link href="/" passHref>
<HeaderIcon
inactiveIcon={<AiOutlineHome />}
activeIcon={<AiFillHome />}
/>
</Link>
Then change HeaderIcon to the following code. Notice I'm using useRouter from Next.js to handle active and inactive state.
import { useRouter } from "next/router";
const HeaderIcon = ({ onClick, href, inactiveIcon, activeIcon }, ref) => {
const router = useRouter();
return (
<a href={href} onClick={onClick} ref={ref}>
<div>{router.pathname ? activeIcon : inactiveIcon}</div>
</a>
);
};
export default React.forwardRef(HeaderIcon);
function HeaderIcon(props) {
const [isActive, setIsActive] = useState(false);
const { inactiveIcon, activeIcon } = props;
return (
<div onClick={() => setIsActive(!isActive)}>
{isActive ? activeIcon : inactiveIcon}
</div>
);
}
export default HeaderIcon;
I hope this will be helpful for you. Thanks
Actually I want another component to Re-render if some changes are made in some other component, parent of both component contain some other component that I don't want them to Re-render. just want when the function is executed it went back to parent and only Re-render the specific component. can't use Window.location.reload because it refresh all the items anything that can rerender only the triggered component. following code is just meant for the idea. as changes are done in First it must be reflected in the other component
`
{/* Parent Component*/}
class Parent extends React.Component {
constructor() {
super();
this.state = {
}
}
render() {
return (
<>
<SecondComponent />
<firstComponent />
<anotherComponent />
<anotherComponent />
<anotherComponent />
</>
);
}
}
export default Parent;
{/* 1 child component */}
import { React } from "react";
const FirstComponent = () => {
const handleChange=(event) =>{
const {name, value}=event.target
localStorage.setItem(name, value)
}
return (
<>
<div className="container-fluid">
<div className="row">
<div className="col-11 col-md-10 mx-auto">
<h1>All Searches</h1>
<input type='text' name='tab1' onChange={handleChange} />
<input type='text' name='tab2' onChange={handleChange} />
</div>
</div>
</div>
</>
);
}
export default FirstComponent;
{/* 2nd Child Component */}
import React from 'react';
import { NavLink } from 'react-router-dom'
class SecondComponent extends React.Component {
constructor(){
super();
this.state={
tab1:localStorage.getItem("tab1"),
tab2:localStorage.getItem("tab2"),
}
}
render() {
return (
<>
<div className="d-inline-flex" style={{ background: "#242F84", width: "100%" }}>
<NavLink to="/" className="Home">
<p className="mb-0 FS_28 px-2 White" >Home</p>
</NavLink>
<NavLink to="/AllSearches">
<p className="mb-0 White">All Searches</p>
</NavLink>
<NavLink to="/AllSearches">
<p className="mb-0 White">{this.state.tab1}</p>
</NavLink>
<NavLink to="/AllSearches">
<p className="mb-0 White">{this.state.tab2}</p>
</NavLink>
</div>
</>
);
}
}
export default SecondComponent;
`
To re-render a component the standard way is to change its state. The question is - If a component's state is not changed, why would you want to re-render it?
I see you are using local storage - I suggest you use local state as much as you can in stead of local storage to manage this type of information.
I'm trying to display the details of a clickable object on a new page. I've tried a few examples from React Router Pass Param to Component with limited success.
The only one that "kind of" worked was Alexander Luna's suggestion to access via ID in component. However, while this returns the id number, I can't access any other values, like "title".
I have tried globalStore, however, the error message told me that it isn't defined. I'm not sure that's my best option or not.
Ultimately I want the whole object back as I plan to use context with See 'D' below.
App) I have commented out my previous attempts
class App extends Component {
render() {
return (
<React.Fragment>
<Navbar />
<Switch>
<Route exact path="/" component={ProductList} />
<Route path="/cart" component={Cart} />
<Route exact path="/details/:id" component={Details} />
{/* <Route exact path="/details/:id" render={(props) => <Details globalStore={globalStore}
{...props} /> } /> */}
{/* <Route exact path="/details/:id" render={(props)=>{ <Details id={props.match.params.id}/>}}
/> */}
<Route component={Default} />
Details page I want to render in.
import React, { Component } from "react";
export default class Details extends Component {
render() {
return(
<div>
<h2>{this.props.match.params.id}</h2>
<h2>{this.props.match.params.title}</h2>
</div>
The product page, I'm using this link to click through to details.
xport default class Product extends Component {
render() {
const { id, title, img, price, inCart } = this.props.product;
return (
<ProductWrapper className="col-9 mx-auto col-md-6 col-lg-3 my-3">
<div className="card">
<div className="img-container" onClick={() => console.log('you clicked container')}
>
<Link to={`/details/${ this.props.product.id }`} >
<img src={img} alt="product" className="card-img-top" />
</Link>
D - This is how the original code looked, I want to use the {title} tags but I don't know if I need "value => " etc.
<ProductConsumer>
{value => {
const {
id,
company,
img,
info,
price,
title,
size,
} = value.Product;
return (
<div className="container py-5">
{/* title */}
<div className="row">
<div className="col-10 mx-auto text-center text-slanted text-blue my-5">
<h1>{title}</h1>
</div>
</div>
You need an extra parameter
<Route exact path="/details/:id/:title" component={Details} />
export default class Details extends Component {
render() {
return(
<div>
<h2>{this.props.match.params.id}</h2>
<h2>{this.props.match.params.title}</h2>
</div>
);
}
}
// In Product component
<Link to={`/details/${ this.props.product.id }/${this.props.product.title}`} >
<img src={img} alt="product" className="card-img-top" />
</Link>
Try to read the params in the constructor like this:
constructor(props)
{
super(props)
const { match: { params } } = this.props;
var id = params.id
this.state = {
id : id,
}
}
and then read the id from the state.
If you want to pass the whole object you can send it through the url in base64 like this :
<Link to={`/details/+btoa( this.props.product )} >
<img src={img} alt="product" className="card-img-top" />
</Link>
And recieving it in the constructor like the previous snippet en parse it to string with the function atob() and then to json.