Passing child component class as props to parent component in React - reactjs

How to pass child component class as props to parent component in React.
My Parent component code :
import React, { Component } from 'react';
import { DashBoard } from './DashBoard/DashBoard';
import { DashBoard } from './Details/Details';
class ContentArea extends Component {
render() {
return (
<div className="content-wrapper">
<DashBoard />
<Details />
</div>
)
}
}
export default ContentArea;
And my child component code :
import React, { Component } from 'react';
export class DashBoard extends Component {
render() {
return (
<h1>This is DashBoard Page.</h1>
);
}
}
And my Route.js code :
import React, { Component } from 'react';
import { render } from 'react-dom';
import { BrowserRouter as Router, Route } from 'react-router-dom';
import { App } from './App';
import { DashBoard } from './components/DashBoard/DashBoard';
import { Details } from './components/Details/Details';
export class AppRoute extends Component {
render() {
return (
<Router>
<div>
<Route exact path={'/'} component={App} />
<Route path={'/DashBoard'} component={DashBoard} />
<Route path={'/Details'} component={Details} />
</div>
</Router>
);
}
}
App.js :
import React, { Component } from 'react';
import SideBar from './components/SideBar';
import Footer from './components/Footer';
import Header from './components/Header/Header';
import ContentArea from './components/ContentArea';
export class App extends Component {
render() {
return (
<div className="skin-purple">
<Header />
<SideBar />
<ContentArea />
<Footer/>
</div>
);
}
}
Now I want to pass my all child component as props to the parent component. And while routing the child component should get render inside the parent component.
Can anyone help me how to achieve that??

Since ContentArea is in App component and you wish to render DashBoard and Details in it, you could specify nested Routes at ContentArea level.
export class AppRoute extends Component {
render() {
return (
<Router>
<div>
<Route path={'/'} component={App} />
</div>
</Router>
);
}
}
import { DashBoard } from './DashBoard/DashBoard';
import { Details } from './Details/Details';
class ContentArea extends Component {
render() {
return (
<div className="content-wrapper">
<Route exact path={'/DashBoard'} component={DashBoard} />
<Route exact path={'/Details'} component={Details} />
</div>
)
}
}
export default ContentArea;

Related

BrowserRouter does not render view of another component in the same page

I am having a very simple app with Carousel. Each slide has a button. When the user clicks on the buttons, it should show the corresponding page at the bottom container. I am passing individual Slide from the parent component as a property called content. Below is my code
Snippet from Slidebar.js which is passing the slides to SlideContent
<div css={SliderBarCss}>
{this.props.slides.map((slide, i) => (
<SlideContent key={i} content={slide} />
))}
</div>
SlideContent.js
/** #jsx jsx */
import React from 'react';
import { BrowserRouter, Link } from 'react-router-dom';
import Routes from './Routes';
import { css, jsx } from '#emotion/core'
export default class SlideContent extends React.Component {
constructor(props) {
super(props);
}
render(){
<div>
<h1>{this.props.content.title}</h1>
<p>{this.props.content.description}</p>
<BrowserRouter>
<Link to={this.props.content.link}><button>{this.props.content.button}</button>
</Link>
</BrowserRouter>
</div>
)
}
}
I have defined the Routes in another file Routes.js
import React, { Component } from 'react';
import { css, jsx } from '#emotion/core'
import { Route, Link, Switch, Redirect } from 'react-router-dom';
import Component1 from '../innerComponents/Component1';
import Component2 from '../innerComponents/Component2';
import HomeComponent from '../innerComponents/Home';
class Routes extends Component{
constructor(props){
super(props);
}
render(){
return(
<Switch>
<Route exact path="/Home" component={HomeComponent} />
<Route exact path="/">
<Redirect to="/Home" />
</Route>
<Route exact path="/Component1" component={Component1} />
<Route exact path="/Component2" component={Component2} />
</Switch>
)
}
}
export default Routes;
below is my app.js where I want my content to show up on button click.
function App() {
return (
<div className="App">
<SliderContainer/>
<BrowserRouter>
<Route component={Routes}></Route>
</BrowserRouter>
</div>
);
}
The URL on the top is changing but the view is not. Really appreciate any help
SOLUTION:
I removed the BrowserRouter element from SlideContent.js and MainContent.js. Added it as a parent to both SliderContainer and MainContent. Shown below are all changed the files
Removed BrowserRouter from SlideContent.js
export default class SlideContent extends React.Component {
constructor(props) {
super(props);
}
render(){
<div>
<h1>{this.props.content.title}</h1>
<p>{this.props.content.description}</p>
<Link to={this.props.content.link}><button>{this.props.content.button}</button>
</Link>
</div>
)
}
Removed BrowserRounter from MainContent.js
class MainContent extends React.Component{
render(){
return(
<Route component={Routes}></Route>
)
}
}
Added BrowserRouter to the parent of SliderContainer and MainContent
app.js
function App() {
return (
<div className="App">
<BrowserRouter>
<SliderContainer/>
<MainContent/>
</BrowserRouter>
</div>
);
}
export default App;

React context : state flow broken from Provider to Consumer

I want to try to transfer the record from state through several components using Consumer and Provider. I have a value in the ShoppingBasketProvider component that I want to pass to the ShoppingBasket component, but at this point it doesn't output anything and equals undefined. Tell me what I'm doing wrong.
I have next components:
ShoppingBasketContext:
import React, { Component, PureComponent } from "react";
export const ShoppingBasketContext = React.createContext();
export default class ShoppingBasketProvider extends Component {
state = {
shoppingBasketItems: 11
}
render() {
return (
<ShoppingBasketContext.Provider shoppingBasketItems={ this.state.shoppingBasketItems }>
{this.props.children}
</ShoppingBasketContext.Provider>
)
}
}
app:
import React, {PureComponent} from 'react'
import './App.scss';
import Shop from '../../page/shop/shop.js'
import AboutUs from '../../page/aboutUs/aboutUs.js'
import Menu from '../menu/menu.js'
import ShoppingBasketProvider from '../shoppingBasketProvider/shoppingBasketProvider.js'
import { BrowserRouter, Switch, Route, Redirect, Router } from "react-router-dom";
export default class App extends PureComponent {
render() {
return (
<main>
<ShoppingBasketProvider>
<BrowserRouter>
<Menu />
<Switch>
<Route path="/" exact children={<Shop />} />
<Route path="/aboutus" children={<AboutUs />} />
<Redirect to="/" />
</Switch>
</BrowserRouter>
</ShoppingBasketProvider>
</main>
);
}
}
ShoppingBasket:
import React, {PureComponent} from 'react'
import { ShoppingBasketContext } from '../shoppingBasketProvider/shoppingBasketProvider.js';
export default class ShoppingBasket extends PureComponent {
render() {
return (
<div>
<ShoppingBasketContext.Consumer>
{shoppingBasketItems => (
<React.Fragment>
Shopping cart: <span>{shoppingBasketItems}</span>
</React.Fragment>
)}
</ShoppingBasketContext.Consumer>
</div>
)
}
}
The prop you pass to the provider must be called value. See suggested change below
return (
<ShoppingBasketContext.Provider value={ this.state.shoppingBasketItems }>
{this.props.children}
</ShoppingBasketContext.Provider>
)

React router : blank page

Here is how the router I defined :
import React from 'react';
import {BrowserRouter, Switch, Route} from 'react-router-dom';
import PersonsList from './PersonsList';
import Error from './Error'
import Person from './Person'
const Router = () => (
<BrowserRouter>
<Switch>
<Route path="/persons" strict={false} component={PersonsList}/>
<Route path="/persons/:id" component={Person}/>
<Route component={Error}/>
</Switch>
</BrowserRouter>
);
export default Router;
The first route works perfectly.
The problem is that in the PersonsList, when I try to reach the /persons/:id route, I get a blank page.
Here is the code I use for redirection in the PersonsList component :
static propTypes = {
history: PropTypes.object
};
handleRedirection = (aPerson) => {
this.props.history.push(`/persons/${aPerson.id}`);
}
...
{this.state.persons.map(aPerson => (
<React.Fragment key={aPerson.id}>
<div className="row" onClick={this.handleRedirection.bind(this,aPerson)}>
Here is the Person component :
import React from 'react';
import PropTypes from 'prop-types';
import { withRouter } from 'react-router';
class Person extends React.Component {
static propTypes = {
match: PropTypes.object
};
constructor(props){
super(props);
console.log('the selected person : ' + this.props.match.params.id);
}
render(){
return(
<div>A person</div>
)
}
}
export default withRouter(Person);
I can see the console.log output but no rendering of the <div>A person</div>.
Question
Why the second route returns a blank content knowing its component's constructor is called? Why the rendering is not processed ?
i try this.props.history.push('/home'); code part but not correct running.
you can see my component codes in the below.
my full component code :
class Full extends Component {
render() {
return (
<div className="app">
<Header/>
<div className="app-body">
<Sidebar {...this.props}/>
<main className="main">
<Breadcrumb/>
<Container fluid>
<Switch>
<Route path="/dashboard" name="Dashboard" component={Dashboard}/>
<Route path="/applications" name="Applications" component={Applications}/>
<Route path="/roles" name="Roles" component={Roles}/>
<Route path="/poc" name="poc" component={Poc}/>
<Redirect from="/home" to="/dashboard"/>
</Switch>
</Container>
</main>
<Aside/>
</div>
<Footer/>
</div>
);
}
}
Dashboard component code :
class Dashboard extends Component {
constructor(props) {
super(props);
}
render() {
return (
<div className="animated fadeIn">
<div>test</div>
</div>
)
}
}
export default Dashboard;
History Code:
import {createBrowserHistory} from 'history';
export const history = createBrowserHistory();

react-router v4.2.2 Switch isn't working; always showing the main component

I'm using react-router to direct a set of cards on the main page, to other individual pages. However, when I click on a card, the new page renders underneath the set of cards, when what I want is to render ONLY the new page. I think the problem may have to do with that my App.js holds the main page inside it, but I don't know where I should put it, if there should be a separate link to it, etc? I would appreciate any help! Thank you
here is the code for the App.js
import React from 'react';
import Routes from '../containers/routes.js';
import ProjectCards from '../containers/project_cards.js';
export default class App extends React.Component {
render() {
return(
<div>
<ProjectCards />
<Routes />
</div>
);
}
}
here is the main container:
import React from 'react';
import { connect } from 'react-redux';
import { Link } from 'react-router-dom';
import ProjectCard from '../components/project_card.js';
import Project1 from '../components/project1.js';
class ProjectCards extends React.Component {
render() {
var projectCards = this.props.projects.map((project, i) => {
return (
<div key={i}>
<Link to={`/${project.title}`}>
<ProjectCard title={project.title} date={project.date} focus={project.focus}/>
</Link>
</div>
);
});
return (
<div>{projectCards}</div>
);
}
}
function mapStateToProps(state) {
return {
projects: state.projects
};
}
export default connect(mapStateToProps)(ProjectCards);
here is the routes container:
import React from 'react';
import Project1 from '../components/project1.js';
import { connect } from 'react-redux';
import { Route, Switch } from 'react-router-dom';
import { withRouter } from 'react-router';
class Routes extends React.Component{
render() {
var createRoutes = this.props.projects.map((project, i) => {
return <Route key={i} exact path={`/${project.title}`} exact component={Project1}/>
});
return (
<Switch>
{createRoutes}
</Switch>
);
}
}
function mapStateToProps(state) {
return {
projects: state.projects
};
}
export default withRouter(connect(mapStateToProps)(Routes));
Set you App file as entry for all components e.g
import React, { Component } from 'react';
import { BrowserRouter, Switch, Route } from 'react-router-dom';
import Home from '../../ui/components/user/home/Home.jsx';
import Header from './header/Header.jsx';
import Fakebook from '../../ui/components/user/fakebook/Fakebook.jsx';
import Dashboard from '../../ui/components/user/dashboard/Dashboard.jsx';
import NotFound from '../../ui/pages/NotFound.jsx';
export default class App extends Component{
render(){
return (
<BrowserRouter>
<div>
<Header />
<Switch>
<Route exact path="/" component={Fakebook}/>
<Route exact path="/Home" component={Home}/>
<Route exact path="/Dashboard" component={Dashboard} />
<Route exact path="/Dashboard/:userId" component={Dashboard}/>
<Route component={NotFound}/>
</Switch>
</div>
</BrowserRouter>
)
}
}
Now if you studied it you will notice a <Header /> component which is not in a route. I did it that way because my header is constant across my whole app.
This is how I setup my route I make my Route the second file after the index.js file so all my route can be visible.

URL change but page does not refresh

I am using react router 4. I have two components 1- ShopLogin 2- Shopper. I am trying to redirect from ShopLogin component to Shopper component after button click.
Everything is working fine. URL is also changing after button click. I am able to see 'Hello' also.
But the problem is i am able to see both component on browser after button click. component is not refreshing. not sure why it is happening. Below are my code.
import React from 'react';
import PropTypes from 'prop-types';
export class ShopLogin extends React.Component {
constructor(props) {
super(props);
this.state = {
};
}
SignIn(e) {
e.preventDefault();
this.context.router.history.push('/shopper');
}
render() {
return (
<div>
<button onClick={this.SignIn.bind(this)}>SignIn</button>
</div>
);
}
}
ShopLogin.contextTypes = {
router: PropTypes.object
}
export default ShopLogin;
My Index.js
import React from 'react';
import ReactDOM from 'react-dom';
import ShopLogin from './ShopLogin';
import Shopper from './Shopper';
import { HashRouter,Route } from 'react-router-dom';
ReactDOM.render((
<HashRouter>
<div>
<Route path="/" component={ShopLogin} />
<Route path="/shopperlogin" component={ShopLogin} />
<Route path="/shopper" component={Shopper} />
</div>
</HashRouter>
), document.getElementById('root'))
My Shopper.js
import React, { Component } from 'react';
export class Shopper extends Component {
constructor(props)
{
super(props);
this.state = {
};
}
render()
{
return (
<div>
Hello </div>
);
}
}
export default Shopper;
It will show multiple components since on the route '/shopper'. The Routes checks successfully to the ShopLogin Component with the path '/' and it checks successfully to the Shopper Component with the path '/shopper'.
I would create a parent Component e.g. Main that just presents the child components and define the routes like this
import IndexRoute from react-router
import { HashRouter,Route, IndexRoute } from 'react-router-dom';
resort your routes to
<HashRouter>
<Route path='/' component={Main}>
<Route path='/shopper' component={Shopper} />
<IndexRoute component={ShopLogin} />
</Route>
</HashRouter>
Create your parent component for ShopLogin and Shopper components
class Main extends Component {
render(){
return (
<div>
{this.props.children}
</div>
)
}
Try to reorder your routes and use the exact attribute and wrap all the routes with a Switch.
<HashRouter>
<div>
<Switch>
<Route path="/" component={ShopLogin} />
<Route exact path="/shopper" component={Shopper} />
<Route path="/shopperlogin" component={ShopLogin} />
</Switch>
</div>
</HashRouter>

Resources