Mutiple ReactDOM.render functions? - reactjs

I'm starting to learn react and getting a problem when calling multiple ReactDOM.render functions:
react:
class Header extends React.Component{
render(){
return(
<div>
<p>Test1</p>
</div>
)
}
};
class Main extends React.Component {
render(){
return(
<section>
<p>Test2</p>
</section>
)
}
};
ReactDOM.render(<Main />, document.getElementById('root2'));
ReactDOM.render(<Header />, document.getElementById('root'));
html part:
<body>
<div id="root"></div>
<div id="root2"></div>
</body>
I'm getting the error:
Target container is not a DOM element.
When searching for this problem I got the information that it should be possible to call ReactDom.render multiple times. So I appreciate your help!
Edit: Just tried it with one html tag and changed the id. It seems to have a problem when the id is not "root"...

You are right, you should be able to call render multiple times in your code.
But instead of doing that why don't you do this:
Class App extends Component {
render(){
<React.Fragment>
<Header />
<Main />
</React.Fragment>
}
}
ReactDOM.render(<App />, document.getElementById('root'))
This is easier, correct and performance superior.
I really see no reason as to why soomeone woudld need to put 2 different renderers on one page. Its just putting more strain on the browser for no reason and it will slow down your application.

Related

Difference between <function prop="Hello"> and {function("Hello")}

I am currently learning React and I do not understand when should I use these and when should I not? I have seen tutorials where people just use them seemingly interchangeably. Hence, I would like to know what is the differences between them and when should i or should i not use them.
For example, assuming the "function" named component returns a <div>Hello</div> after the call, I can have the following code.
import {function} from './component';
class X extends React.Component{
render(){
return(
<div>
<function Props1="Hello"/>
</div>
)
}
}
Next,I believe can also have the following code, please correct me if I'm wrong
import {function} from './component';
class X extends React.Component{
render(){
return(
<div>
{function("Hello")}
</div>
)
}
}
So it seems like there are two ways for doing the exact same thing in ReactJS? Are there any reasons I should be using one over the other?
When you render it like <function Props1="Hello"/>, React will create a props object, with the properties and values pairs you passed to it.
When you render it like {function("Hello") your props argument will be a string "Hello".
See snippet below:
function App() {
return(
<React.Fragment>
<Component1
props1="hello"
/>
{Component2("hello")}
</React.Fragment>
);
}
function Component1(props) {
return(
<React.Fragment>
Component1
<div>Props: {JSON.stringify(props)}</div>
<br/>
</React.Fragment>
);
}
function Component2(props) {
return(
<React.Fragment>
Component2
<div>Props: {JSON.stringify(props)}</div>
</React.Fragment>
);
}
ReactDOM.render(<App/>, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"/>
The difference is that first case it is stateful component, so the props has to be passed by something like in your case
Props1=""
then in your function component which in this case is stateful ,you get access to props via this.props.Props1
in second case it is functional component so you can get access to it like for example:
class X extends React.Component{
render(){
return(
<div>
{function("Hello")}
</div>
)
}
}
function function(myprop) {
return <div>{myprop}</div>
}

React : Parsing error: Unterminated JSX contents

I keep getting this syntax error, but have no idea where the end sequence is failing:
import React, { Component } from 'react';
import './App.css';
class App extends Component {
render() {
return (
<div className="App">
<textarea rows="4" cols="50">
<h1>Look at this!</h1>
<h2>This is MAGIC!</h2>
<a href="https://www.mozilla.com/">
<p>Think about all this power of <code>React</code></p>
<textarea />
</div>
);
}
}
export default App;
The <a> element is not closed. I suggest you to add linters it will be easier for you to spot these errors, also it's strange why you editor didn't point that.
You have two unterminated JSX contents in your code. One for the first textarea and one for the a. Here is the fixed code. By the way, I agree with the linter suggestion.
class App extends React.Component {
render() {
return (
<div className="App">
<textarea rows="4" cols="50" />
<h1>Look at this!</h1>
<h2>This is MAGIC!</h2>
Go to Mozilla
<p>
Think about all this power of <code>React</code>
</p>
<textarea />
</div>
);
}
}
ReactDOM.render( <App />, document.getElementById( "root" ) );
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
html <a> tag needs to be closed using </a> if there is any content like text, div, etc.
Go to Mozilla

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}

this.props.children vs this.props.someName

It seems, I see two equal ways to delegate property via props:
let App = React.createClass({
render(){
return (
<Unit someName="Push me!" />
)
}
});
class Unit extends React.Component{
render(){
return (
<button>
<span className="glyphicon glyphicon-heart"/>
{this.props.someName}
</button>
)
}
};
and
let App = React.createClass({
render(){
return(
<Unit>
<span className="glyphicon glyphicon-heart"></span>
Push me now!
</Unit>
)
}
});
class Unit extends React.Component{
render(){
return (
<button>{this.props.children}</button>
)
}
};
What's the general purpose of props.children?
Can I consider it as equal to props.someName?
Could be provided some examples where props.someName doesn't work but props.childred does?
Maybe I am wrong, but I think that the existence of children is just syntactic sugar to allow an HTML-like nesting of elements. As far as I know, it is exactly the same as any other property. In fact, while using JSX you can add children as an ordinary property and it doesn't make any difference.
let App = React.createClass({
render(){
return(
<Unit children={<span className="glyphicon glyphicon-heart">Push me now!</span>}/>
)
}
});
class Unit extends React.Component{
render(){
return (
<button >{this.props.children}</button>
)
}
};
ReactDOM.render(<App/>, document.getElementById('app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>
Generally speaking, this.props.children is used to refer to all the children that are wrapped in a custom component.
<View>
<Text>One</Text>
<Text>Two<Text>
</View>
Here, the two Text elements are children to your View. In the class definition(or equivalent) for your View component, you can refer to all the children components by this.props.children. But I think you already understand this much.
From what I understand, as a rule of thumb, you pass some values/properties, etc as props to a component.
If you want to, for example, render some components in a custom component that you are defining, you need to be able to refer to what components were declared in the implementation code from definition code, so you use this.props.children.
My language is a bit muddled, but I hope this is clear enough.

dom ready event in React

I have some components like below:
Wrapper: wrap Loader and Page
Loader: some animation
Page: page content
code like this:
<body>
<div id="app"></div>
</body>
class Loader extends Component {}
class Page extends Component {}
class Wrapper extends Component {
render() {
return (
<Loader/>
<Page />
);
}
}
ReactDOM.render(<Wrapper />, document.getElementById('app'));
I want hide Loader and show Page component after DOM has compeletely loaded.
How should I write dom ready event in React?
like jQuery: $(window).on('ready')
TL;DR If I understand correctly, the answer is probably "not possible". But there is another solution...
Here's what I think you're trying to do, described as a series of steps:
page starts loading, <Loader /> component shows a "page loading" animation
page finishes loading, <Loader /> component is removed (or hidden) and <Page /> component is inserted (or shown) with the "real" page content.
Here's the problem: remember that you inject your React components into the page like this:
ReactDOM.render(<Wrapper />, document.getElementById('app'));
You can't actually inject a React component until the DOM is loaded. So by that time, either <Loader /> appears for about 2 milliseconds and disappears, or it doesn't appear at all (since the DOM is already loaded by the time it gets injected into the page).
If you're trying to show a throbber or other simple animation (like an animated GIF), I'd try a hybrid approach:
Set up your HTML like this:
<body>
<div id="app"><img src="throbber.gif" /></div>
</body>
In your script tag, include a JQuery "document ready" event handler to load the React component:
class Page extends Component {}
class Wrapper extends Component {
render() {
return (
<Page />
);
}
}
$(document).ready(function () {
ReactDOM.render(<Wrapper />, document.getElementById('app'));
});
Notice that I've left out the <Loader /> - the throbber image is doing the work of the loader.
The idea here is that while the page is loading, the throbber GIF will be throbbing away until the DOM is loaded, at which point JQuery's document ready event will fire & the contents of the div#app will be replaced.
I haven't tried this, but it should work, provided that React actually replaces the content of div#app, rather than just appending stuff to it. If that's not the case, then it's a simple matter of changing the document ready handler to something like this:
$(document).ready(function () {
$('div#app img').remove();
ReactDOM.render(<Wrapper />, document.getElementById('app'));
});
The approach I ended up using (No JQuery needed) is the following:
In the index.html, put the loader element right after the root div
<div id="root">
</div>
<div id="preloader" class="pre-loader">
<img src="..."> </img>
</div>
Then inside your index.js :
document.addEventListener("DOMContentLoaded", function(event) {
ReactDOM.render(
<React.StrictMode>
<Provider store={store}>
<BrowserRouter>
<DashApp />
</BrowserRouter>
</Provider>
</React.StrictMode>,
document.getElementById("root")
);
const loadingScreen = document.getElementById("preloader");
loadingScreen.style.opacity = 0;
loadingScreen.style.display = "none";
});
So basically we simply follow a similar approach to what the other answer suggests, but without the need of JQuery cause we listen to the loading event using
document.addEventListener("DOMContentLoaded", function(event) { }
Another approach would be just placing the loader inside the root div which means React will overwrite it by default when it loads:
<div id="root">
<div id="preloader" class="pre-loader">
<img src="..."> </img>
</div>
</div>
My personal full approach can be seen in this

Resources