Cannot get basic React with JSX example to work - reactjs

Any pointers would be appreciated. I'm new to React and JSX and Babel and am just trying to get something bare-bones working. I've been at this for a while and I'm at a dead end.
Here's my html page:
<!DOCTYPE html>
<html>
<head>
<title>Test React</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script crossorigin src="https://unpkg.com/react#16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom#16/umd/react-dom.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.34/browser.min.js"></script>
<script type="text/babel" src="../TestReact/res/js/main.jsx"></script>
</head>
<body>
<div>Page to Test React Library</div>
<p></p>
<div>
<button onclick="addComponent()">Add Component</button>
</div>
<p></p>
<div id="root">
</div>
</body>
</html>
And here's my "main.jsx" file:
addComponent = function (){
ReactDOM.render(
<h1>Hello, world!</h1>,
document.getElementById('root')
);
};
I'm using Chrome 61.
If I include either type="text/babel" or type="text/jsx" on my script tag, I get an exception: "Uncaught ReferenceError: addComponent is not defined".
If I remove this type attribute on the script tag, then (of course) I get an error for "unexpected token <" because the html/xml is not going to be transpiled.
When I have the type attribute (for jsx/babel) on the script tag removed AND I enclose the html in my addComponent method in quotes, then I get no errors, but I end up with the literal string
"<h1>Hello, world!</h1>"
rendered on the page in the 'root' div instead of an embedded header element - naturally, but at least that tells me that my small javascript and ReactDOM library are imported and working.
So it seems like the problem is that the JSX transpiling is not happening for some reason.
<---- UPDATE 201710011830 ---->
It seems that the problem I'm having is related to having ReactDOM.render called from within a javascript function ("addComponent") in my JSX file that is supposed to handle a button onclick event. If I remove the addComponent function so that main.jsx looks like this:
ReactDOM.render(
<h1>Hello, world!</h1>,
document.getElementById('root')
);
then the h1 element is inserted on the page as it should be.
So the question then becomes, why won't it work the way I initially intended? Is it because of the syntax I used to define that addComponent function within the original JSX script?

You need to add bundle.js to your index.html file like below.
<body>
....
<div id="root"></div>
<script src="/bundle.js"></script>
</body>
bundle.js is the distribution which packs all the react components and dependencies and put them together in your dev environment using webpack.

Add type="text/babel" to your script tag will transform your code which in main.jsx file. I think this transform effect your addComponent function that makes your code doesn't work.
You can try just put the jsx or react component code in main.jsx, like: window.Hello = <h1>hello</h1>; then in the html(or somewhere out of main.jsx), you can write
addComponent = function (){
const Hello = window.Hello;
ReactDOM.render(
<Hello />,
document.getElementById('root')
);
};
But I highly recommend use webpack, a simple demo: https://github.com/yujiangshui/react-i18n-demo

Related

How to use JSX properly for react, i'm getting an error

I'm new in ReactJs n my first code test. The tuto says that this will work:
HTML(index.html):
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>react test</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#16/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom#16/umd/react-dom.development.js" crossorigin></script>
<!-- Load our React code -->
<script src="pba.js"></script>
</body>
</html>
JS(pba.js):
const element = {<h1>Hello, world!</h1>};
ReactDOM.render(
element,
document.getElementById('root')
);
Problem:
pba.js:3 Uncaught SyntaxError: Unexpected token '<'
You should use a build tool like
create react-app, gatsby or next.js
What you are doing here is loading a javascript file directly into an html document.
However the Javascript file has no idea, what React is. If you don't want to use an independent build tool like suggested above, you can use webpack to bundle your code.
Here is a tutorial on how to do this: https://www.valentinog.com/blog/babel/
otherwise look into create react app:
https://www.google.com/search?q=create+react+app&oq=create+react+app&aqs=chrome..69i57j0l7.3442j1j7&sourceid=chrome&ie=UTF-8
Your element component needs to be a function or a class component. Note that doing the following will also work, but using one component as a root component for your app is better than just rendering one element.
const greeting = 'Hello World';
const element = <h1>{greeting}</h1>;
// or const Element = [<h1>{greeting}</h1>, <h1>Hello again</h1>];
ReactDOM.render(element, document.getElementById('root'));
Using function/class component
// pba.js
const Element = () => (<h1>Hello World</h1>)
ReactDOM.render(<Element />, document.getElementById('root'));
and also you need to add babel cdn to transpile your react code, add type text/babel to your script tag. <script type="text/babel" src="pba.js"></script>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>react test</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#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://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.21.1/babel.min.js"></script>
<!-- Load our React code -->
<script type="text/babel" src="pba.js"></script>
</body>
</html>
Just change your pba.js file as follows:
const element = React.createElement("h1", {}, "Hello, world!");
ReactDOM.render(element, document.getElementById("root"));
While this is possible, there are a couple of things wrong with your code.
It looks like goto1 is correct, you can just use the () syntax for this, but you need to use () instead of {}
While goto1 is correct, the first argument in ReactDOM.render(...) does not have to be a function or class (just valid JSX), I am 110% recommending you stick to using functions or classes...
You need to use something like Babel Standalone so your React code can be translated into something a browser will understand
I have made a lot of comments with examples in the demo below, which should help you out.
Demo:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>react test</title>
</head>
<body>
<div id="root"></div>
<div id="root-two"></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>
<!-- Load Babel Standalone -->
<script src="https://unpkg.com/#babel/standalone/babel.min.js"></script>
<!-- Load our React code -->
<!-- Notice the 'type="text/babel"' attribute -->
<script type="text/babel">
// This was done for the sake of simplicity, you can still load your .js file here
// While goto1 is technically correct, I recommend sticking
// to using functions or classes..
const Element = () => {
return ( <h1>Hello, world!</h1> );
}
// This means you can do things like:
// Notice our component from above, Element, is reusable here..
const AnotherElement = () => {
return (
<div style={{textAlign: 'center', color: 'blue'}}>
<Element />
</div>
);
}
// Keep in mind using `()` syntax versus a function or class, means this is not reusable at all..
// The following is NOT reusable!
// const element = ( <h1>Hello, world!</h1> );
// You could also drop the `()` as it is used to group lines of code,
// something like this is also not reusable (but would still work in
// this scenario)!
// const element = <h1>Hello, world!</h1>
// For example, this wouldnt work
// const anotherElement = ( <element /> );
// This would also not work
// class SomeClass extends React.Component {
// render() { return ( <div><element /></div> ) }
// }
// This would not work either
// const SomeComponent = () => {
// return ( <div><element /></div> );
// }
ReactDOM.render(
// goto1 is correct, it looks like you can use an object as you were.
// Please be mindful of this as it is not reusable!
// I recommend sticking to either functions or classes, until you are more comfortable with React
<Element />,
document.getElementById('root')
);
// For the second example, demonstrating how using functions or classes
// is reusable, whereas your original example was not:
ReactDOM.render(
<AnotherElement />,
document.getElementById('root-two')
);
</script>
</body>
</html>

Adding react from separate js file does not work

I was following the 'Add React to a Website' guide on https://reactjs.org/docs/add-react-to-a-website.html#optional-try-react-with-jsx but it does not seem to work correctly for some reason.
The code that does not work:
index.html:
<html>
<head>
<!-- Load React -->
<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"></script>
<!-- Load React component. -->
<script src="test.js"></script>
</head>
<body>
<div id="root"></div>
</body>
</html>
test.js:
ReactDOM.render(
<h1>Hello, world!</h1>,
document.getElementById('root')
);
The code above will produce a blank page but when I add the react code on the index.html page like this:
<script>
ReactDOM.render(
<h1>Hello, world!</h1>,
document.getElementById('root')
);
</script>
It does work.
I have tried to replace
<script src="test.js"></script>
with
<script src="/test.js"></script>
and
<script src="./test.js"></script>
but that still does not work.
Also when I inspect element on the blank page it does show that it loads test.js
Can someone please tell me what I am doing wrong?
As the guide says:
Now you can use JSX in any <script> tag by adding type="text/babel"
attribute to it.
So you need <script src="test.js" type="text/babel"></script>.
Even you can do it without adding text/babel by just using React.creatElement API as recommneded by Dan Abramov, author of redux and part of Reactjs core team.
Here is the working codesanbox: React with no build config

Simple JSX throws error in console

React noob here, I am working on a simple JSX based component with the code below:
<!DOCTYPE html>
<html>
<head>
<title>React Boot camp Day 1</title>
</head>
<body>
<div id='app'></div>
<!--Needed for react code-->
<script crossorigin src="https://unpkg.com/react#16/umd/react.development.js"></script>
<!--Needed for react dom traversal-->
<script crossorigin 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>
console.log('Test React', window.React)
const name = "Callat"
const handle = "#latimeks"
// create components and use jsx
function FirstComponent(props){
return <h1>{props.name}</h1>
}
function TestJSX(){
return (<FirstComponent name={name}/>)
}
ReactDOM.render(<TestJSX/>, document.getElementById('app'))
</script>
</body>
</html>
Running this code yields no UI and in dev tools I see this
Uncaught SyntaxError: Unexpected token < index.html:42
Which is the
function FirstComponent(props){
return <h1>{props.name}</h1>
}
What is wrong here? According to everything I've seen online and in the bootcamp instructions my syntax is correct and this should work.
Can anyone give some insight?
I found an answer to this. Including the CDN was only part of the fix. The second part is to include the following:
<script type="text/babel">//My react code</script>
Once that's done reloading the page works. I really should get more used to the native react ecosystem though.

passing javascript block through the template unescaped

I want to include Reactjs code in my content like this:
<script type="text/babel">
ReactDOM.render(
<div>
<h1>Hello, world!</h1>
this is a link...
</div>,
document.getElementById('root')
);
</script>
I want this code to actual run, not just for display. However, when it passes through the Hugo template it comes out as:
<p><script type="text/babel"></p>
<pre><code> ReactDOM.render(
<div>
<h1>Hello, world!</h1>
<a href="http://www.example.com">this is a link...</a>
</div>,
document.getElementById('root')
);
</script>
</code></pre>
which means it won't run.
Basically, I want content editors to be able to drop in a React Component code and have it run on the page. Thanks.
EDIT:
This is what I want to be the final output of the hugo template:
<html>
<head>
<meta charset="UTF-8" />
<title>Hello World</title>
<script src="https://unpkg.com/react#latest/dist/react.js"></script>
<script src="https://unpkg.com/react-dom#latest/dist/react-dom.js"></script>
<script src="https://unpkg.com/babel-standalone#6.15.0/babel.min.js">
</script>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
ReactDOM.render(
<div>
<h1>Hello!!</h1>
this is a link...
</div>,
document.getElementById('root')
);
</script>
</body>
</html>
but I want the bit between the script tags to be entered in to the markdown page as it will be surrounded by other text, and should not form part of the template
OK, so I worked out the problem.
In order to get this to work you need to make sure that the open
<script>
tag has no whitespace to the left. It must start the line. Otherwise, I guess the template engine will just go ahead and escape it.

ReactJS rendering issue

just began to learn React and here are my very simple JSX and HTML files. I don't see any error in Console (Chrome) when I run it from my http-server. However the button Im expecting to see won't show in the browser. I'm not sure why it does not and what is missing.
Can anyone please help? Also why should we specify type=text/babel" in the tag? If I don't do this, I get an error (unexpected syntax <) in console.
Thanks!
Prem
HTML Code:
<html>
<head>
<title>
!My first React JS Component!
</title>
</head>
<body>
<div id="root"></div>
<script src="react.js"></script>
<script src="script.jsx" type="text/babel"></script>
</body>
</html>
my JSX File:
var Button = React.createClass({
render: function () {
return (
<button> Go! </button>
)
}
});
ReactDOM.render(<Button />, document.getElementById("root"));
You cannot just include the jsx in your site like that - it won't work :)
You need to transpile your jsx via a tool like Webpack.
The official documentation really is excellent and easy to understand, and it should explain how you setup a basic environment.
Also, there are dozens of tutorials on this, but here's a free one that I found helpful and easy to understand on youtube:
React + Redux + Webpack (Feel free to skip the redux part for a starter - really just a popular addon to React for managing state, which you can expand upon later)
For good measure, something like this should work:
<html>
<head>
<meta charset="UTF-8"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.7/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.7/react-dom.js"></script>
</head>
<body>
<div id="app"></div>
<script type="text/babel" src="app.jsx"></script>
</body>
</html>
App.jsx:
ReactDOM.render(
<h1>Hello React!</h1>,
document.getElementById('app')
);

Resources