Adding React to HTML (without create-react-app installation) - javascript

I'm trying to follow this official React Documentation on how to add React to a website.
In file main.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Add React in One Minute</title>
</head>
<body>
<div id="root"></div>
<!-- Load React. -->
<!-- Note: when deploying, replace "development.js" with "production.min.js". -->
<script src="https://unpkg.com/react#18/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom#18/umd/react-dom.development.js" crossorigin></script>
<!-- Load our React component. -->
<script src = "states_clock.js"> </script>
</body>
</html>
In file states_clock.js
// states_clock.js
'use strict';
const domContainer = document.getElementById('root');
const root = ReactDOM.createRoot(domContainer);
class Clock extends React.Component {
render() {
return (
<div>
<h1>Hello, world!</h1>
<h2>It is {this.props.date.toLocaleTimeString()}.</h2>
</div>
);
}
}
function tick() {
root.render(<Clock date={new Date()} />);
}
setInterval(tick, 1000);
Both files are in the same folder.
When I open the html page in chrome, I get the error message:
Uncaught SyntaxError: Unexpected token '<' (at states_clock.js:11:7)
The < being complained about is that of the div in the js file.

This:
class Clock extends React.Component {
render() {
return (
<div>
is not JavaScript syntax - it's JSX syntax.
When you do
<script src = "states_clock.js"> </script>
as you would with any normal script tag, you're telling the browser to interpret and run it as a standard JavaScript file, which doesn't work, because it isn't. Add the attribute type="text/babel" to the script tag so it doesn't get run as JavaScript, and so that Babel Standalone sees that it's a script tag for it to process.
<script src="states_clock.js" type="text/babel"></script>
You could also write the JSX inline, like this:
<script crossorigin src="https://unpkg.com/react#18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom#18/umd/react-dom.development.js"></script>
<div id='root'></div>
<script src="https://unpkg.com/#babel/standalone/babel.min.js"></script>
<script type="text/babel">
'use strict';
const domContainer = document.getElementById('root');
const root = ReactDOM.createRoot(domContainer);
class Clock extends React.Component {
render() {
return (
<div>
<h1>Hello, world!</h1>
<h2>It is {this.props.date.toLocaleTimeString()}.</h2>
</div>
);
}
}
function tick() {
root.render(<Clock date={new Date()} />);
}
setInterval(tick, 1000);
</script>

So, thanks to the comment by ChrisG, I understood that we're not supposed to use JSX in this part of the tutorial.
In that spirit, here's my solution:
'use strict';
const e = React.createElement;
const domContainer = document.getElementById('root');
const root = ReactDOM.createRoot(domContainer);
class Clock extends React.Component {
render() {
return e('div', null, e("h1", null, "Hello, world!"),
e("h2", null, "It is ", this.props.date.toLocaleTimeString(), "."));
};
}
function tick() {
root.render(e(Clock, {date: new Date()}, null))
}
setInterval(tick, 1000);
P.S.: Here's useful link that transforms JSX code into non-JSX code.

Related

Having issues loading Scripts in my NextJS React application

I am trying to load some scripts in my NextJS application. I have followed the procedures outlined in the NextJS documentation but it doesn't seem to work in my application.
The link to the documentation is, https://nextjs.org/docs/basic-features/script.
I load the scripts in the _document.js file like this.
_document.js
import Document, { Html, Head, Main, NextScript } from "next/document";
import Script from "next/script";
class MyDocument extends Document {
static async getInitialProps(ctx) {
const originalRenderPage = ctx.renderPage;
// Run the React rendering logic synchronously
ctx.renderPage = () =>
originalRenderPage({
// Useful for wrapping the whole react tree
enhanceApp: (App) => App,
// Useful for wrapping in a per-page basis
enhanceComponent: (Component) => Component,
});
// Run the parent `getInitialProps`, it now includes the custom `renderPage`
const initialProps = await Document.getInitialProps(ctx);
return initialProps;
}
render() {
return (
<Html>
<Head />
<body>
<Main />
<NextScript />
<Script
src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"
id={`jquery-1${+new Date()}`}
strategy="beforeInteractive"
></Script>
<Script
src="/webflow.js"
id={`webflow-1${+new Date()}`}
strategy="beforeInteractive"
></Script>
<Script
src="https://ajax.googleapis.com/ajax/libs/webfont/1.6.26/webfont.js"
id={`webfont-1${+new Date()}`}
strategy="beforeInteractive"
></Script>
<Script strategy="lazyOnload" id={`load-font-1${+new Date()}`}>
{`WebFont.load({
google: {
families: ["DM Sans:regular,500,700"]
}})`}
</Script>
</body>
</Html>
);
}
}
export default MyDocument;
I also tried this by putting the scripts in the Head tag but it was the same result.
_document.js
import Document, { Html, Head, Main, NextScript } from "next/document";
import Script from "next/script";
class MyDocument extends Document {
static async getInitialProps(ctx) {
const originalRenderPage = ctx.renderPage;
// Run the React rendering logic synchronously
ctx.renderPage = () =>
originalRenderPage({
// Useful for wrapping the whole react tree
enhanceApp: (App) => App,
// Useful for wrapping in a per-page basis
enhanceComponent: (Component) => Component,
});
// Run the parent `getInitialProps`, it now includes the custom `renderPage`
const initialProps = await Document.getInitialProps(ctx);
return initialProps;
}
render() {
return (
<Html>
<Head>
<Script
src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"
id={`jquery-1${+new Date()}`}
strategy="beforeInteractive"
></Script>
<Script
src="/webflow.js"
id={`webflow-1${+new Date()}`}
strategy="beforeInteractive"
></Script>
<Script
src="https://ajax.googleapis.com/ajax/libs/webfont/1.6.26/webfont.js"
id={`webfont-1${+new Date()}`}
strategy="beforeInteractive"
></Script>
<Script strategy="lazyOnload" id={`load-font-1${+new Date()}`}>
{`WebFont.load({
google: {
families: ["DM Sans:regular,500,700"]
}})`}
</Script>
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
);
}
}
export default MyDocument;
I confirmed that the scripts were not working by checking the network tab and also as there functionalities that were meant to work on the website and dependent on the scripts were not working.

Adding React to an existing page and getting URL parameter inside .js

Based on official how to:
Add React to Website at https://reactjs.org/docs/add-react-to-a-website.html
I created test.html with content:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Add React in One Minute</title>
</head>
<body>
<h2>Add React in One Minute</h2>
<p>This page demonstrates using React with no build tooling.</p>
<p>React is loaded as a script tag.</p>
<!-- We will put our React component inside this div. -->
<div id="like_button_container"></div>
<!-- Load React. -->
<!-- Note: when deploying, replace "development.js" with "production.min.js". -->
<script src="https://unpkg.com/react#16/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom#16/umd/react-dom.development.js" crossorigin></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<!-- Load our React component. -->
<script src="test.js"></script>
</body>
</html>
And test.js:
'use strict';
const e = React.createElement;
class LikeButton extends React.Component {
constructor(props) {
super(props);
this.state = { liked: false };
}
componentDidMount() {
axios.get(`http://localhost:4000/api/v1/cars`)
.then(result => {
console.log(result.data[0].make);
})
}
render() {
if (this.state.liked) {
return 'You liked this.';
}
return e(
'button',
{ onClick: () => this.setState({ liked: true }) },
'Like'
);
}
}
const domContainer = document.querySelector('#like_button_container');
ReactDOM.render(e(LikeButton), domContainer);
The code above is working well.
I'm able to press Like button and see the change, also able to use libraries such as Axios.
Now I want to open http://localhost/test.html?param1=111&param2=222 and get these param1 and param2 variables inside test.js - React. Is that possible? How to achieve this?
Many thanks
Just as you perform a fetch in ComponentDidMount, you can check query params in the same lifecycle event. Building on the link shared by #Olian04, here's how that'd look:
componentDidMount() {
const urlParams = new URLSearchParams(window.location.search);
if (urlParams.has("param1")) {
console.log(urlParams.get("param1"));
} else {
console.log("param1 was not found");
}
if (urlParams.has("param2")) {
console.log(urlParams.get("param2"));
} else {
console.log("param2 was not found");
}
}

How to perform import/export in client-side React JSX using Babel-Standalone

I'm using Babel-Standalone to use JSX in a React application without using NPM. Babel apparently translates 'import' statements into 'require' statements; importing 'require.js' and other dependencies to make this work produces more errors.
Surely, there must be a simple way to perform an import/export in the context of client-side JSX. Please advise (no Node/NPM/Webpack solutions are sought here; CDN of appropriate library(ies) and rewrite of import statement, etc., are sought).
<!doctype html>
<html lang="en-us">
<head>
<title>React JSX Babel-Standalone Import/Export Problem</title>
<meta charset="utf-8">
</head>
<body>
<div id="root"></div>
<script src="https://unpkg.com/react#16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom#16/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/babel-standalone#6/babel.min.js"></script>
<script type="text/babel">
// See MyExport.js text below this SCRIPT
// Goal: to employ <MyExport /> in the return of App.
// import MyExport from "./MyExport";
const App = () => {
return (
<div>Hello</div>
);
};
ReactDOM.render(<App />, document.querySelector("#root"));
</script>
<!-- MyExport.js:
const MyExport = () => {
return (
<div>MyExport</div>
);
};
export default MyExport;
-->
</body>
</html>
There is a solution: (1) The JSX script containing the export must be included in a SCRIPT element along with the others; it cannot simply be referenced by another script without. (2) Both that JSX script and the JSX script importing from it must have the custom attribute data-plugins="transform-es2015-modules-umd" along with the expected attribute type="text/babel". Run the following HTML, a modification of what was provided in the question, which provides the solution (you'll have to create MyExport.js locally to run it):
<!doctype html>
<html lang="en-us">
<head>
<title>React JSX Babel-Standalone Import/Export Problem</title>
<meta charset="utf-8">
</head>
<body>
<div id="root"></div>
<script src="https://unpkg.com/react#16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom#16/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/babel-standalone#6/babel.min.js"></script>
<script data-plugins="transform-es2015-modules-umd" type="text/babel" src="./MyExport.js"></script>
<script data-plugins="transform-es2015-modules-umd" type="text/babel">
import MyExport from "./MyExport";
const App = () => {
return (
<MyExport/>
);
};
ReactDOM.render(<App />, document.querySelector("#root"));
</script>
<!-- MyExport.js:
const MyExport = () => {
return (
<div>MyExport element is imported!</div>
);
};
export default MyExport;
-->
</body>
</html>
I hope this helps someone else.
you should include first all needed component files, then run the app js file
Example:
<div id="root-react"></div>
<script src="https://unpkg.com/react#16/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom#16/umd/react-dom.development.js" crossorigin></script>
<script src="https://unpkg.com/babel-standalone#6/babel.min.js" crossorigin></script>
And the file's tree is something like:
js/app.js
js/subcomponent.js
The app.js content is for example:
"use strict";
class MainReact extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<strong>app.js</strong> is loaded<br/>
<SubComponent />
</div>
)
}
}
ReactDOM.render(<MainReact />, document.getElementById("root-react"));
subcomponent.js content:
"use strict";
class SubComponent extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<span> SubComponent-is-working </span>
)
}
}
customElements.define('subcomponent', SubComponent);
The file inclusion in the html file should be:
<script type="text/babel" src="js/subcomponent.js"></script>
<script type="text/babel" src="js/app.js"></script>
Hope it helps somebody.
CodePen demo
Babel isn't a module bundler or a module system implementation, babel is just a transpiler to provide access to the latest JS features that aren't supported in the browser or node.
If you want to use ES Modules without any third parties like webpack, rollup, etc. have a look at https://developers.google.com/web/fundamentals/primers/modules.
You should be able to do something like:
<script type="module">
import MyExport from "./url/to/MyExport.mjs";
const App = () => {
return (
<div>Hello</div>
);
};
ReactDOM.render(<App />, document.querySelector("#root"));
</script>
JS Modules via script tags is only supported in the latest versions of major browsers: https://caniuse.com/#feat=es6-module
Also, you'll need to workaround the fact that babel-standalone needs your script tags to be text/babel EDIT: the workaround is using a data-type="module" tag as well as the type="text/babel" tag: https://babeljs.io/docs/en/babel-standalone#usage

React JS Uncaught ReferenceError : require is not defined

I'm currently trying to get React to work by CDN.
When I run the index.html file manually it works. But when I put my files onto a web server like XAMPP, I get hit with
Uncaught ReferenceError : require is not defined
index.html:
<html>
<head>
<title>TestApp</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.2.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.2.0/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.26.0/babel.min.js"></script>
<script src="./node_modules/moment/moment.js"></script>
</head>
<body>
<div id="app"></div>
<script type="text/babel" src="./react.js"></script>
</body>
</html>
react.js:
const Aest = ({test}) => {
return (
<div>WATss {test}</div>
)
}
class Test extends React.Component{
constructor(){
super()
this.state={
test: 0
}
}
inc(){
this.setState({
test: ++this.state.test
})
}
render(){
return(
<React.Fragment>
<div>test: {this.state.test}</div>
<button onClick={()=>this.inc()}>Add</button>
<Aest test={this.state.test}/>
</React.Fragment>
)
}
}
ReactDOM.render(<Test />,document.getElementById('app'));
require is not understood by default in some web severs, to allow it to be recognized first. use require js. npm install it. and import it.

"React without Node/npm" - Geting error - "Uncaught ReferenceError: exports is not defined"

I am set up a project in reactjs. The main thing important to be noted that I am not using node or npm to set up the project. It means, I directly use all scripting library files after downloading them and added them in my project. But, I am getting error of "exports is not defined".
One more thing to be noted that I cannot use import keyword in my project.
index.html
<!DOCTYPE html>
<html>
<head>
<title>Learn Reactjs</title>
<script src="react.min.js"></script>
<script src="react-dom.min.js"></script>
<script src="browser.min.js"></script>
</head>
<body>
<div id="root"></div>
<script type="text/babel" src="DropDown.js"></script>
<script type="text/babel" src="index.js"></script>
</body>
</html>
index.js
'use strict';
var DropDown = require('DropDown');
var HelloMessage = React.createClass({
render: function () {
return (
<div>
<h1>Hello {this.props.message}!</h1>
<DropDown />
</div>
);
}
});
ReactDOM.render(<HelloMessage message="World" />, document.getElementById('root'));
DropDown.js
'use strict';
var DropDown = React.createClass({
render: function () {
return (
<div>
<h1>i am DropDown</h1>
</div>
);
}
});
export default DropDown;
I found the solution of my problem.
Step 1: keep index.html as same as above.
Step 2: replace index.js file as per below code:
'use strict';
var DropDown = window.DropDown;
var HelloMessage = React.createClass({
render: function () {
return (
<div>
<h1>Hello {this.props.message}!</h1>
<DropDown />
</div>
);
}
});
ReactDOM.render(<HelloMessage message="World" />, document.getElementById('root'));
Step 3: replace DropDown.js file with the below code:
'use strict';
window.DropDown = React.createClass({
render: function () {
return (
<div>
<h1>i am DropDown</h1>
</div>
);
}
});

Categories

Resources