react - children component not showing - reactjs

I'm trying to insert a child component inside another child component, but my code is not working. Following codes are the structure i'm trying to build.
const AddProductPage= () => {
return (
<PageTemplate>
<ProductTemplate>
<AddProduct />
</ProductTemplate>
</PageTemplate>
);
};
const PageTemplate= ({children}) => {
return (
<div className={cx('pagetemplate')}>
<HeaderContainer />
<main>
{children}
</main>
<Footer />
</div>
);
};
class ProductTemplate extends Component {
render() {
return (
<div className={cx('product-template')}>
...
<div className={cx('display')}>
{this.props.children}
</div>
</div>
);
}
}
class AddProduct extends Component {
render() {
return (
<div className={cx('addproduct')}>
addproduct
</div>
);
}
}
I'm trying to insert AddProduct component in ProductTemplate component as a child, which is inserted in PageTemplate component as a child. AddProductPage, however, is not showing AddProduct component. I'd be grateful if anyone can help.

I've run your code. May be you'r missing default export statements.
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import AddProductPage from './AddProductPage';
ReactDOM.render(<AddProductPage />, document.getElementById('root'));
AddProductPage.js
import React from 'react';
import PageTemplate from './PageTemplate';
import ProductTemplate from './ProductTemplate';
import AddProduct from './AddProduct';
const AddProductPage= () => {
return (
<PageTemplate>
<ProductTemplate>
<AddProduct />
</ProductTemplate>
</PageTemplate>
);
};
export default AddProduct;
PageTemplate.js
import React from 'react';
const PageTemplate= ({children}) => {
return (
<div>
<main>
{children}
</main>
</div>
);
};
export default PageTemplate;
ProductTemplate.js
import React,{Component} from 'react';
class ProductTemplate extends Component {
render() {
return (
<div>
<div>
{this.props.children}
</div>
</div>
);
};
};
export default ProductTemplate;
AddProduct.js
import React, {Component} from 'react';
class AddProduct extends Component {
render() {
return (
<div>
addproduct
</div>
);
};
};
export default AddProduct;
Output is this :
addproduct

Here`s a Fiddle of your code
Works Fine!. I have removed cx API. I suppose the problem might be with className resolution. Check in the dom hierarchy weather the Children DOM Node exists and they have received their respective classnames.
const PageTemplate= ({children}) => {
return (
<div className={'pagetemplate'}>
<HeaderContainer />
<main>
{children}
</main>
<Footer />
</div>
);
};

Related

Having a problem with the state not being transferred to another component

I am having a problem that the value made by one component cannot be delivered to another component. I made a state in the top component and I think I connected it well. But the desired array made of state is empty. Sorry for the long code to ask.
The code below is the top component, and InCart is the state that I'm having issues with.
App.js:
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import Site from './Site/Site';
import { useState } from 'react';
import RealCart from './RealCart/RealCart';
function App() {
const [Inproducts,setInproducts] = useState([])
const [InCart, setInCart] = useState([]);
return (
<BrowserRouter>
<Routes>
<Route path='/realCart' element={<RealCart InCart={InCart} setInCart={setInCart}/>} />
<Route path='/loginHome' element={<Site InCart={InCart} setInCart={setInCart} Inproducts={Inproducts} setInproducts={setInproducts}/>}/>
</Routes>
</BrowserRouter>
);
}
export default App;
There are many components connected in the middle, so I omitted it, but the props are connected as well. And I got the json file from here.
Section5Bottom.jsx:
import axios from 'axios';
import React, { useEffect } from 'react';
import "../section5.css";
import Section5Card from './Section5Card';
function Section5Bottom({Inproducts, setInproducts, InCart, setInCart}) {
useEffect (()=> {
axios.get("/data/products.json").then((data)=>{
setInproducts(data.data.products);
});
},[setInproducts]);
return (
<div id='Section5Bottom'>
{
Inproducts.map((product)=>{
return <Section5Card key={`key-${product.id}`} product={product} InCart={InCart} setInCart={setInCart}/>
})
}
</div>
)
}
export default Section5Bottom;
When I clicked the icon below the file, I used the InCart made in App.js to put the array value of the selected card in the array. If I check the console here, the array is good as shown in this photo.
Section5Card.jsx:
import '../section5.css';
import {FaCartPlus} from 'react-icons/fa';
import { useDispatch } from 'react-redux';
import './card.css';
function Section5Card({product, InCart, setInCart}) {
const dispatch = useDispatch();
const handleCart = () => {
const cartItem = {
id : product.id,
image : product.image,
provider : product.provider,
price : product.price,
name : product.name
}
setInCart([...InCart, cartItem])
}
return (
<div>
<div id='CardWrap'>
<div>
<img id='Section5CardImg' src={product.image} />
</div>
//************************************
<div>
<FaCartPlus size='20' style={{color:'black', position:'relative', top:'124px', left:'130px', cursor:'pointer'}} onClick={()=>{dispatch({type:"ADD"}); handleCart()}} />
</div>
//*************************************
<div id='CardBot'>
<div id='CardBotBPrice'>
₩{product.price}
</div>
<div id='CardBotTag'>
{product.people?
<span id='CardBotTagPeople'>
{product.people}명
</span>:
<>
<span id='CardBotTagSale'>
{product.sale}
</span>
</>}
</div>
</div>
</div>
</div>
)
}
export default Section5Card;
And the below file is the one I wish to bring up in the InCart state. But even if I check with the console, the array is empty as shown below:
RealCart.jsx:
import React from 'react'
import Top from '../Site/Header/Top'
import Navi from '../Site/Header/Navi/Navi'
import Cart from './Components/Cart';
import CartHeader from './Components/CartHeader';
function RealCart(InCart, setInCart) {
console.log(InCart)
return (
<div>
<Top />
<Navi />
<Cart />
<CartHeader />
</div>
)
}
export default RealCart;
In your RealCart.jsx file you have to wrap your props with {} and it will be like
function RealCart({InCart, setInCart}) {
console.log(InCart)
return (
<div>
<Top />
<Navi />
<Cart />
<CartHeader />
</div>
)
}

How to pass prop from one component to another?

I need to pass prop called name from one React component to another, but something goes wrong. Could you tell me how to do it right?
Thanks in advance
import React from 'react';
export class Greeting extends React.Component {
render() {
return (
<h1>Hello World and {this.props.name}</h1>
)
}
}
import React from 'react';
import ReactDOM from 'react-dom';
import Greeting from './Greeting';
function App() {
return (
<div>
<Greeting name='Alex' />;
<h2> Welcome, {Greetings.props.name} </h2>
</div>
);
}
export default App;
two things:
looks like you are mixing class and functional components, i recommend going for functional as its more common now. in that case the Greeting will look like this:
export function Greeting(props) {
return (
<h1>Hello World and {props.name}</h1>
)
}
you are passing the prop the the component, but you cant access it from its parent. you can create another variable for that:
const greetingName = "Alex";
function App() {
return (
<div>
<Greeting name={greetingName} />;
<h2> Welcome, {greetingName} </h2>
</div>
);
}
In Greeting.js you have missed parameter
App.js
import React, { useState } from 'react';
import Greeting from './Greeting';
const App = () => {
const [name, setName] = useState("")
return (
<div>
<Greeting name="Alex" />
</div>
)
}
export default App
Greeting.js
import React from 'react'
const Greeting = (props) => {
return (
<div>
<h1>Hello World and My name is {props.name}</h1>
</div>
)
}
export default Greeting

Extract Data from API and show in another page

This question may sound silly to some people, but I am really confused on how to do it
I have 3 file: App.js, HomePage.js and Profile.js
App.js :
import React from "react"
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
import HomePage from "./components/HomePage";
import Profile from "./components/Profile"
function App() {
return (
<Router>
<Switch>
<Route path="/" exact component={HomePage} />
<Route exact path="/profile/:profileId" component= {Profile} />
</Switch>
</Router>
);
}
export default App;
From here, the default page it will go to is HomePage.js
HomePage.js:
import React, { Component } from "react";
import axios from "axios";
import { Link } from "react-router-dom";
class HomePage extends Component {
constructor() {
super();
this.state = {
userData: [],
}
}
componentDidMount() {
axios.get("XXXXXXXX").then((response) => {
const userDataList = response.data.users;
this.setState({
userData: userDataList
})
})
}
render() {
const userGrid = this.state.userData.map((user, index) => {
return (
<div key={index}>
<Link to={`/profile/${user.id}`}>
<img src={user.profilepicture} />
<p>{user.name}</p>
</Link>
</div>
)
})
return (
<div className="App">
<div className="card">
<div className="card__top">
<span className="card__title">
<p>Select An Account</p>
</span>
</div>
<div className="card__bottom">
<div className="card__table">
{userGrid}
</div>
</div>
</div>
</div>
)
}
}
export default HomePage;
In HomePage.js, I am able to show the profile picture and name of the user from API.
In the next page which is Profile.js , I am able to print the ID of the user.
Profile.js:
import React, { Component } from "react";
class Profile extends Component{
componentDidMount(){
const uid = this.props.match.params.profileId;
}
render() {
console.log(this.props.match);
return(
<h1>{this.props.match.params.profileId}</h1>
)
}
}
export default Profile;
As you can see I am printing the ID of user.
Here I also want to show the Profile Picture of the user which I selected in HomePage.js
This I am not able to do it.
JSON file:
{ - users: [-{id:1, name:"abc", profilepicture: "xxxxx.jpeg"}, ]}
You need to store a global state in your applicattion, which you can access from every connected component. This is a more complex topic. redux is a good framework to handle your global state changes.
Here is a tutorial: https://appdividend.com/2018/06/14/how-to-connect-react-and-redux-with-example/
I found it pretty hard to learn redux, but in the end it takes away a lot of pain. Because this is a problem you gonna have in every app you build with react.
You need use Context API o redux
Example context API: https://ibaslogic.com/react-context-api/
Context's well to little projects, but Redux performs better.
App.js
import React from "react"
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
import HomePage from "./components/HomePage";
import Profile from "./components/Profile"
import { UsersProvider } from "./UsersProvider.js";
function App() {
return (
<Router>
<UsersProvider>
<Switch>
<Route path="/" exact component={HomePage} />
<Route exact path="/profile/:profileId" component= {Profile} />
</Switch>
</UsersProvider>
</Router>
);
}
export default App;
UsersContext.js
import React, { Component } from "react"
const UsersContext = React.createContext();
const UsersProvider = UsersContext.Provider;
const UsersConsumer = TodosContext.Consumer;
class MyContext extends Component {
state = {
value: null,
};
setValue = (value) => {
this.setState({ value });
};
render() {
return (
<UsersProvider value={{ setValue, value }}>{this.props.children}
</UsersProvider>
)
}
}
export { UsersContext, UsersProvider, UsersConsumer }
HomePage.js
import React, { Component } from "react";
import axios from 'axios';
class HomePage extends Component {
componentDidMount() {
axios.get("XXXXXXXX").then((response) => {
const userDataList = response.data.users;
// updating your context
this.props.context.setValue(userDataList);
})
}
render() {
const userGrid = this.props.context.value.map((user, index) => {
return (
<div key={index}>
<Link to={`/profile/${user.id}`}>
<img src={user.profilepicture} />
<p>{user.name}</p>
</Link>
</div>
)
})
return (
<div className="App">
<div className="card">
<div className="card__top">
<span className="card__title">
<p>Select An Account</p>
</span>
</div>
<div className="card__bottom">
<div className="card__table">
{userGrid}
</div>
</div>
</div>
</div>
)
}
}
export default HomePage;
Profile.js
import React, { Component } from "react";
import { UsersConsumer } from "./UsersContext.js";
class Profile extends Component{
render() {
return(
<UsersConsumer>
{users => (
<h1>{users.value.find(user => user.id === this.props.match.params.profileId)}</h1>
)}
</UsersConsumer>
)
}
}
export default Profile;

It doesn't work Consumer/Provider in the example - the tab hangs

Why does the React tab in my browser hang when visualizing these components? What am I doing wrong? I just want to transfer the text to another component using Provider and Consumer.
Menu component:
import React, {PureComponent, createContext} from 'react'
import { Link } from "react-router-dom";
import './menu.scss';
import ShoppingBasket from '../shoppingBasket/shoppingBasket.js';
const UserContext = React.createContext({})
export const UserProvider = UserContext.Provider
export const UserConsumer = UserContext.Consumer
export default class Menu extends PureComponent {
render() {
return (
<div className="head">
<nav>
<Link to="/">Home</Link>
<Link to="/aboutus">About Us</Link>
</nav>
<UserProvider username={`name`}>
<ShoppingBasket />
</UserProvider>
</div>
)
}
}
ShoppingBasket component:
import React, {PureComponent} from 'react'
import UserProvider from '../menu/menu.js';
import UserConsumer from '../menu/menu.js';
export default class ShoppingBasket extends PureComponent {
render() {
return (
<UserConsumer>
{context => {
return(
<div>
<h2>Profile Page of {context.username}</h2>
</div>
)
}}
</UserConsumer>
)
}
}
As per the React Context Api ,in Context Provider, data should be passed using the "value" prop , what you are doing it passing the username prop to the provider, what you should try is
<UserProvider value={`name`}>
<ShoppingBasket />
</UserProvider>
and while in the consumer
<UserConsumer>
{value => {
return(
<div>
<h2>Profile Page of {value}</h2>
</div>
)
}}
</UserConsumer>

Using React-Dom's render more than once

Is it at all possible to use react-dom's render more than once in a react spa, in particular in a nested child component? For example:
index.jsx:
import React from 'react';
import { render } from 'react-dom';
import sampleComponent from './sampleComponent';
render(<SampleComponent />, document.getElementById('app'));
sampleComponent.jsx:
import React from 'react';
import { render } from 'react-dom';
const SampleComponent = () => (
<div>
<h1>hello world</h1>
<div id="foo" />
</div>
);
export default SampleComponent;
render(<h1>it's me again</h1>, document.getElementById('foo'));
To use render more than once is a complicated way.
You don't need that.
You already create a valid component. Just wrap it into another and use more then once. En example:
const SampleComponent = () => (
<div>
<h1>hello world</h1>
<div id="foo" />
</div>
);
const WrapperComponent = () => (
<div>
<SampleComponent />
<SampleComponent />
</div>
);
export default WrapperComponent;

Resources