How much static HTML should I serve with React? - reactjs

How much static HTML should I serve with React as opposed to just leaving it in the HTML file?
(I am just getting started with React.)
I have a single page application, which, greatly simplified, looks like this:
<body>
<div id="container">
<div id="header">
<div id="header_dynamic_content">
</div>
</div>
<div id="dynamic_content">
</div>
<div id="footer">
</div>
</div>
</body>
Is it best/common practice to use React to only handle the dynamic content and to leave everything that is static in the HTML file? Or should I use React Components to serve everything?
So this?
class DynamicOne extends React.Component {
render() {
return (
/* My Content */
);
}
}
class DynamicTwo extends React.Component {
render() {
return (
/* My Content */
);
}
}
ReactDOM.render(<DynamicOne />, document.getElementById('header_dynamic_content'));
ReactDOM.render(<DynamicTwo />, document.getElementById('dynamic_content'));
or this?
class DynamicOne extends React.Component {
render() {
return (
/* My Content */
);
}
}
class DynamicTwo extends React.Component {
render() {
return (
/* My Content */
);
}
}
class App extends React.Component {
render() {
return (
<div>
<div id="header">
<div id="header_dynamic_content">
<DynamicOne />
</div>
</div>
<div id="dynamic_content">
<DynamicTwo />
</div>
<div id="footer">
</div>
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById('container'));

According to React Documentation:
Applications built with just React usually have a single root DOM node. If you are integrating React into an existing app, you may have as many isolated root DOM nodes as you like.
Ref
Happy coding :)

Related

React adding an element programmatically with a HOC

Is there a way using a High Order Component to add elements programatically to a Component? I was wondering if there was a way using React.createElement to append the component's children? Here is the code that I have so far:
import React, { Component } from 'react'
import ReactDOM from 'react-dom'
function addAnElement(WrappedComponent) {
return class Enhancer extends WrappedComponent {
render() {
const elementsTree = super.render()
// Programatically add a child?
// Update elementTree.props.children somehow?
return elementsTree
}
}
}
class JustSomeText extends Component {
render() {
return (
<div>
<p>A long time ago, in a galaxy far, far away.</p>
{/* I want to add an element here? */}
</div>
)
}
}
function App() {
const ExtendedComponent = addAnElement(JustSomeText)
return (
<div className="App">
<ExtendedComponent />
</div>
)
}
export default App
ReactDOM.render(<App />, document.getElementById('root'))
I'm also interested in other, more effective ways to achieving the same result.
The simplest way to achieve this (although it does not use HOC) is using the children prop in React.
class JustSomeText extends Component {
render() {
return (
<div>
<p>A long time ago, in a galaxy far, far away.</p>
{this.props.children}
</div>
)
}
}
function App() {
return (
<div className="App">
<JustSomeText>
<p>more text!</p>
</JustSomeText>
</div>
)
}
This will render the following:
<div className="App">
<div>
<p>A long time ago, in a galaxy far, far away.</p>
<p>more text!</p>
</div>
</div>
Refer to this for further detail on children - https://reactjs.org/docs/composition-vs-inheritance.html

Custom namespaced attribute in JSX/React

As I already figured out, React's JSX doesn't support namespace tags by default. But lets say I have the following component:
render() {
return (
<div><!-- This should contain th:text -->
...
</div>
);
}
and I want this component to be rendered to:
<div th:text="value">
...
</div>
How can I achieve, that th:text="value" will be added to the rendered output?
Found the solution a few minutes later:
const i18n = {
"th:text": "${#foo.bar}"
};
render() {
return (
<div {...i18n}>
...
</div>
);
}

React - Extremely simple Codepen will not show up

I have a codepen. I need it to literally say "Hello world" with React. I can't get the code to render.
I have Babel set as the pre-compiler.
I have both React and ReactDOM linked.
Here is all of the HTML:
<div id="app"></div>
Here is all of the JS:
class App extends React.Component {
render() {
<div>
<p>Hello!</p>
</div>
}
}
ReactDOM.render(<App />, document.getElementById('app'));
I need to get this going for an interview in an hour or two. Just can't get it working here. Help!
You forgot to return the component in render:
render() {
return (
<div>
<p>Hello!</p>
</div>
);
}
You need to return the content from the render function to display.
class App extends React.Component {
render() {
return (
<div>
<p>Hello!</p>
</div>
}
}

Implement HTML Entity Decode in react.js

I am outputting the text using API from the server, and I have an admin which has the html fields for facilitating filling the content. The issue in here that now the text displaying with html codes. How I can get rid of that undeeded html codes. I guess I have to use html entity decode? How I will implement that in react project? Below you see that the text illustrates not only text and html code.
export class FullInfoMedia extends React.Component {
render() {
const renderHTML = (escapedHTML: string) => React.createElement("div", { dangerouslySetInnerHTML: { __html: escapedHTML } });
return (
<div>
<div className="about-title">
<div className="container">
<div className="row">
<img className="center-block" src={this.props.about.image}/>
<h2>{this.props.about.title}</h2>
{renderHTML(<p>{this.props.about.body}</p>)}
</div>
</div>
</div>
</div>
);
}
}
You can use dangerouslySetInnerHTML, but be sure you render only your input, not users. It can be great way to XSS.
Example of using:
const renderHTML = (rawHTML: string) => React.createElement("div", { dangerouslySetInnerHTML: { __html: rawHTML } });
And then in a component:
{renderHTML("<p>&nbsp;</p>")}
Even though you can use dangerouslySetInnerHTML it's not really a good practice, and as stated by Marek Dorda it's a great thing for making your app XSS vulnerable.
A better solution would be to use the he library. https://github.com/mathiasbynens/he
This would be an example of how would your component look with it.
import he from 'he'
export class FullInfoMedia extends React.Component {
render() {
const renderHTML = (escapedHTML: string) => React.createElement("div", { dangerouslySetInnerHTML: { __html: escapedHTML } });
return (
<div>
<div className="about-title">
<div className="container">
<div className="row">
<img className="center-block" src={this.props.about.image}/>
<h2>{this.props.about.title}</h2>
{ he.decode(this.props.about.body) }
</div>
</div>
</div>
</div>
);
}
}
Also, if it were my codebase, I would most likely move the decoding to the API call, and in the component just consume the value that comes from the store
You can simply try this, it decodes text and then display.
<p dangerouslySetInnerHTML={{__html:"&nbsp;"}}/>

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