Rendering a child component via React-router
So I was struggling with this code. I have a component that takes a child as a pillar, and it needs to be the base of all the pages that I post.
Base.jsx:
import React from 'react';
import PropTypes from 'prop-types';
import { Link, NavLink } from 'react-router-dom';
const Base = ({ child }) => (
<div>
<div className="top-bar">
<div className="top-bar-left">
<NavLink to="/">React App</NavLink>
</div>
<div className="top-bar-right">
<Link to="/login">Log in</Link>
</div>
</div>
{child.render()} // HERE IS THE CHILD TO RENDER
</div>
);
Base.propTypes = {
child: PropTypes.object.isRequired
};
export default Base;
Then, in app.jsx where lies ReactDom.render()
, I have this:
import React from 'react';
import ReactDom from 'react-dom';
import injectTapEventPlugin from 'react-tap-event-plugin';
import getMuiTheme from 'material-ui/styles/getMuiTheme';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import {BrowserRouter, Switch, Route} from 'react-router-dom';
import LoginPag from './components/LoginPag.jsx';
import Base from './components/Base.jsx';
import HomePage from './components/HomePage.jsx';
// for MaterialUI to work properly
injectTapEventPlugin();
const TestLogin = (props) => {
return (<Base child={LoginPag} />);
};
const TestBase = (props) => {
return(<Base child={HomePage}/>)
};
ReactDom.render((<BrowserRouter><MuiThemeProvider muiTheme={getMuiTheme()}>
<div>
<Switch>
<Route exact path="/" component={TestBase} />
<Route exact path="/login" component={TestLogin}/>
</Switch>
</div>
</MuiThemeProvider>
</BrowserRouter>), document.getElementById('react-app'));
Finally, HomePage and LoginPag look the same, and here's HomePage.jsx:
import React from 'react';
import { Card, CardTitle } from 'material-ui/Card';
const HomePage = {
render() {
return (<Card className="container">
<CardTitle title="React Application" subtitle="This is the home page." />
</Card>);
}
};
export default HomePage;
Now my question is: is it possible to get rid of these abstractions TestLogin
and TestBase
?
My ultimate goal is to have something like this:
<Route exact path="/" component={Base(HomePage)} />
, that is, get rid of the abstraction layer and display it directly on one line.
Thanks in advance.
EDIT . Thanks to the Anuragasaurus, I could achieve what I wanted. Can I do this with the class too? The class is declared as class LoginPage extends React.Component
and has a method render()
.
source to share
With simple object AND class:
const Base = ({ child }) => (
<div>
<div className="top-bar">
<div className="top-bar-left">
<NavLink to="/">React App</NavLink>
</div>
<div className="top-bar-right">
<Link to="/login">Log in</Link>
</div>
</div>
{child}
</div>
);
and
const TestLogin = (props) => {
return (<Base child={<LoginPage/>} />);
};
const TestBase = (props) => {
return(<Base child={<HomePage}/>/>)
};
To answer the whole question:
<Route exact path="/" render={()=><Base child={<HomePage/>} />} />
<Route exact path="/login" render={()=><Base child={<LoginPage/>} />}/>
source to share