How to render only specific components in Reactjs - reactjs

Is there a way to render only some components in Reactjs
class UserproPage extends Component{
render(){
return(
<>
<Topbar/>
<Navbar/>
<div>
<h1>Hello</h1>
</div>
</>
)
}
The <Navbar/> has menu button that are common to all the pages hence I do not want it to render them every time I click on links on the menu.

you can make a condition in your <Navbar/> component whether you display or not the menu button
example :
class Navbar extends Component {
let display = true;
render() {
return (
<div>This is my component.</div>
{display && <button>menu</button>}
);
}
}
the menu button is displayed only when display variable is true

Related

ReactJS, React-Router: Calling parent function

I am working on a React App, trying to call a parent method from a child component, some code of the parent component below:
class NavigationBar extends Component {
constructor(props){
super(props);
this.state={isLoggedIn: false};
}
updateLoginState(){
alert("Login from NavigationBar");
}
GetBar() {
//const isLoggedIn = this.props.isLoggedIn;
if (false){ //isLoggedIn
return this.UserNavBar();
}
return this.StrangerNavBar();
}
StrangerNavBar(){
return (
<div>
<HashRouter>
<div>
{/* ... */}
<div className="content">
<Route exact path="/LoginCC" loginUpdate={this.updateLoginState} component={LoginCC} />
</div>
</div>
</HashRouter>
</div>
);
}
render() {
return (
this.GetBar()
);
}
}
export default NavigationBar;
This component is supposed to redirect the user to different content pages based on whether or not he is logged in, using a Router. If a button is clicked in LoginCC.js the method updateLoginState should be invoked which just displays a message for now. The child content page LoginCC.js looks as follows:
class LoginCC extends Component {
constructor(props){
super(props);
this.state = {isLoggedIn: false};
}
render() {
return (
<div>
<HashRouter>
{/* ... */}
<Button variant="primary" size="lg" block onClick={this.props.loginUpdate}>
Log in
</Button>
{/* ... */}
</HashRouter>
</div>
);
}
}
export default LoginCC;
I passed the method reference as a prop to LoginCC when rendering this component using the Router, so a message should pop up if I press the button, but nothing happens.
Am I passing the prop incorrectly or something else I've missed? I'm new to React so any help is appreciated.
Route doesn't pass any custom props to components. You should use other method to pass functions.
One of solutions is:
<Route exact path="/LoginCC" render={
props => <LoginCC {...props} loginUpdate={this.updateLoginState}/>
} />
Note that updateLoginState will not get this when called. You should either bind it or declare it as an arrow function to get the correct this.
Also check the Context documentation.

how can I dynamically attach sidebar components to multiple instances of sidebar?

I'm new to React and building out a design a ran into a problem.
I have a component called SideBar. I am using this component two times, one on each side of the page.
The problem is that I would like to add different components to each instance of the SideBar component. These would be lists of various items and etc. I assumed I could next component tags but the sidebar component doesn't output.
import React, { Component } from "react";
import SideBar from "./WorkspaceComponents/SideBar";
import ScrollerBox from "./WorkspaceComponents/SideBarComponents/ScrollerBox";
class Workspace extends Component {
render() {
return (
<main className="reely-workspace">
<SideBar position="SideBarLeft">
<ScrollerBox />
</SideBar>
<SideBar position="SideBarRight" />
</main>
);
}
}
export default Workspace;
Your sidebar component should receive a children prop and render it out.
Something like this:
class Sidebar extends Component {
render() {
const {children} = this.props;
return (
<div className="sidebar">
<h1>Sidebar</h1>
{children}
</div>
)
}
}
Check out this post on react docs to understand how to compose react components: https://reactjs.org/docs/composition-vs-inheritance.html
You can make your SideBar Component a wrapper component which wraps around the content given in it.
Making SideBar Component a Wrapper Component :
class Sidebar extends Component {
render() {
return (
<div className="sidebar">
// You can add any custom element here //
{this.props.children}
</div>
)
}
}
All your element passed inside the SideBar Component will now be rendered as a part of SideBar along with what it contains.
Way to consume the wrapper component:
<SideBar>
<Content1></Content1>
<Content2></Content2>
<Content3></Content3>
</SideBar>

simplest approach of dynamically adding components in react

currently working on react. I have two components lets say ad and home . Inside home components i have one image and on click event of that image i want to render ad inside home component below image. Is there any simples method . thank you!
check this. i think this is what you want
//dynamically generate div
let DynamicDiv=()=>{
return (<div>
<p>i am here</p>
</div>)
}
class App extends Component {
constructor(props){
super(props)
this.state={
visible:false //visibility of Component
}
this.divVisiblity=this.divVisiblity.bind(this) //function is bind when user clicks on pic
}
divVisiblity(){
//this function will get called when user clicks on function
this.setState(()=>{return {visible:!this.state.visible}}) //changes visible state of Component when user clicks
}
render() {
return (
<div>
<div className="App">
{/* onClick is assigned function named divVisiblity */}
<img onClick={this.divVisiblity} src="https://placekitten.com/g/200/300" alt="test"/>
{/*this is ternary if else statement in js */}
{/* if visible = true ,display Component else dont */}
<div>
{this.state.visible && <DynamicDiv/>}
</div>
);
}
}
I think that will help to you.
export default class HomeComponent extends Component<Props> {
constructor(props) {
super(props);
this.state = {
renderAdComponent: false
};
this.onClickHandler = this.onClickHandler.bind(this);
}
onClickHandler() {
this.setState({renderAdComponent: !this.state.renderAdComponent})
}
render() {
return (
<View>
<Image onClick={this.onClickHandler}/>
{this.state.renderAdComponent ? <AdComponent/> : null}
</View>
);
}
}
What #sdkcy suggested is okay but the ternary operator isn't really needed. You can do the following
{ this.state.isAdShown && <ComponentToShow /> }
This gets rid of the useless : null result.

How can I open a specific modal in a specific page with url in react?

I use "react-router-modal" and it works well. When I click the link the modal will appear correctly with its new path in browser's address bar.
class MainComponent extends Component {
render(){
return(
<section>
<BrowserRouter>
<div>
<ModalLink path='/foo' component={FooModal}>
Say Hello
</ModalLink>
<ModalContainer/>
</div>
</BrowserRouter>
</section>
)
}
}
class FooModal extends Component{
render(){
return(
<div>Foo modal says hi!</div>
)
}
}
I added this linen in routes.js file too.
<ModalRoute path="/foo" parentPath="/" component={FooModal}/>
But I need it viceversa.
It means When I enter the path show the page with this modal open but only a blank page will be shown.

Element not being displayed when div is removed in react

I am quite new to react but I am trying to pass element from the Course component to my Coursebox component. I am doing this successfully but the button is being displayed since I am not passing that with this.prompt. I would like to remove the div id="course" from the HTML because I only want the course component to be displayed within the couresebox component.
This is my JSX code
class Course extends React.Component {
render() {
return (
<div className="course">
<h3>{this.props.coursename}</h3>
<h4> {this.props.status} {this.props.progress}</h4>
<button>Start exercise</button>
</div>
);
}
}
ReactDOM.render( < Course />, document.getElementById('course'));
class Coursebox extends React.Component {
render() {
return (
<div>
<Course coursename="Negotiation" progress= "20%" status="Progress"/>
<Course coursename="Frontend" progress="56%" status="Progress"/>
<Course coursename="Food" status="Progress" progress="43%"/>
</div>
);
}
}
ReactDOM.render( < Coursebox />, document.getElementById('coursebox'));
and HTML
<header id="header">
</header>
<h3 id="search"></h3>
<div id="coursebox"></div>
<div id="course"></div>
When I remove the nothing is being displayed on the page apart from the header. Since I am passing the element from Course to the Coursebox component, shouldn't I be able to remove the course div from the HTML?
If it is still needed, why is that?
Is there a way for me to only display the button when a course name is being passed?
Thanks :)
Avoid rendering the course component. Ideally there should be just one render method and all other components should be called from that component. So render on CourseBox component only.
class Course extends React.Component {
render() {
console.log("hey")
return (
<div className="course">
<h3>{this.props.coursename}</h3>
<h4> {this.props.status} {this.props.progress}</h4>
<button>Start exercise</button>
</div>
);
}
}
class Coursebox extends React.Component {
render() {
return (
<div>
<Course coursename="Negotiation" progress= "20%" status="Progress"/>
<Course coursename="Frontend" progress="56%" status="Progress"/>
<Course coursename="Food" status="Progress" progress="43%"/>
</div>
);
}
}
React.render(<Coursebox />, document.getElementById('coursebox'));
Working JS fiddle http://jsfiddle.net/kmbw9wgt/3/
1.) See this line
ReactDOM.render( < Course />, document.getElementById('course'));
You are explicitly asking react to render Course in a div which has id 'course'.
If you remove this, it will not render separately, but only from within Coursebox element.
Then you can safely remove that div.
2.) Yes, you can only show button when course name is passed. Using If condition ternary operator. Add your button in following way:
<h3>{this.props.coursename}</h3>
<h4> {this.props.status} {this.props.progress}</h4>
{ this.props.coursename ? (<button>Start exercise</button>): null}

Resources