ReactJs browser Cannot read property 'keys' of undefined - javascript

HTML code:
<div id="content"></div>
<script src="build/react.min.js"></script>
<script src="build/react-dom.min.js"></script>
<script src="https://cdn.bootcss.com/babel-core/6.1.19/browser.min.js"></script>
<script src="ex1.jsx" type="text/babel"></script>
JSX code:
// create class
var HelloWord = React.createClass({
render: function () {
return (
<div>
<p>Hello Word!</p>
</div>
);
}
});
// show content
ReactDOM.render(
<HelloWord></HelloWord>, document.getElementById('content')
);
Console message after run:
Uncaught TypeError: Cannot read property 'keys' of undefined
Why?

I also ran into the same issue and while surfing the internet I found that there was a problem with the babel-core version that I used. I replaced that with another and got my code to work.
Try this
HTML
<div id="content"></div>
<script src="build/react.min.js"></script>
<script src="build/react-dom.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.34/browser.min.js"></script>
<script src="ex1.jsx" type="text/babel"></script>
JSX
var HelloWord = React.createClass({
render: function () {
return (
<div>
<p>Hello Word!</p>
</div>
);
}
});
// show content
ReactDOM.render(
<HelloWord></HelloWord>, document.getElementById('content')
);
It should work for you too.
Update:
You can use babel-standalone package for babel compilation with the newer version since babel-browser is deprecated.
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.25.0/babel.min.js"></script>

Related

Access variables defined in <head> or external script from React component

I am integrating a third-party library into my React app.
They provide this script I need to add to my <head>:
index.html
<head>
<script>
var externalVariable1 = externalVariable1 || {};
var externalVariable2 = externalVariable2 || {};
</script>
// tag.min.js gives value to these variables
<script async src="//example.com/tag.min.js"></script>
</head>
I need to use access these two variables from my component. I tried the following but I get 'externalVariable1' is not defined error. Any thoughts?
MyScreen.js
import React from 'react';
const MyScreen = () => {
return (
<React.Fragment>
<div>
<h2>Hello!</h2>
</div>
<div id='myId'>
{externalVariable.push(function() { externalVariable2.display();})}
</div>
</React.Fragment>
);
}
export default MyScreen;
If you want to access variables defined in the global scope from inside of a React component, you can typically do that by accessing the variable through the window object.
See the example below:
function App(){
return <h1>The secret is {window.secret}</h1>
}
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>
<!-- Adding some global variables outside of React -->
<script>
var secret = "hello";
</script>
<div id="root"></div>

Cannot get context element text

This is pretty straight forward but I caannit get the expected result. I want to iterate over a set of paragraph elements and get their text node using .each() function although I get the entire document text nodes.
Here is the code
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<body>
<main>
<p>Kon</p>
<p>Mule</p>
</main>
<p>Hello riko</p>
<h2 hidden data-modal-target=".modal-progress">Header 2</h2>
</body>
<script type="text/javascript">
$(function () {
// console.log($("p"))
$("p").each((index)=> {
console.log( $( this ).text())
// console.log(index)
})
})
</script>
</html>
Instead of getting:
Kon
Mule
Hello Riko
I get this:
Kon
Mule
Hello riko
Header 2
$(function () {
// console.log($("p"))
$("p").each((index)=> {
console.log( $( this ).text() + index)
// console.log(index)
})
})
three times.
Where am I wrong?
this is not accessible in arrow functions. You need to use regular functions to do that:
$("p").each(function(index) {
console.log($(this).text())
// console.log(index)
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<main>
<p>Kon</p>
<p>Mule</p>
</main>
<p>Hello riko</p>
<h2 hidden data-modal-target=".modal-progress">Header 2</h2>
Or you need to get the native JS array from the jQuery collection using get() and use forEach() on it:
$("p").get().forEach((item) => {
console.log($(item).text())
})
You are doing everything correct as per code. Something is wrong with your environment. here is working code
https://jsfiddle.net/RanjeetKumarGautam/w6ojokp1/
$(function () {
// console.log($("p"))
$("p").each((index)=> {
console.log( $( this ).text())
// console.log(index)
})
})

Invalid Component Element in React.JS

I've been going through a react.js tutorial, with a simple hello world example. I can't find a reason why the following shouldn't work, but I keep getting this error.
Uncaught Error: Invariant Violation: React.render(): Invalid component element.
I have the following code. It seems to work if I do React.createElement, but not for the JSX elements.
<!doctype html>
<html>
<head>
<script src="https://fb.me/react-0.13.3.js"></script>
<script src="https://fb.me/JSXTransformer-0.13.3.js"></script>
<script type="text/jsx">
document.body.onload = function(){
console.log("shuff")
var HelloWorld = React.createClass({
render: function(){
return <div>Hello, Ian Shuff!</div>;
}
});
React.render( new HelloWorld(), document.getElementById("test"))
}
</script>
</head>
<body>
<div id="test"></div>
</body>
</html>
You should pass to render <HelloWorld />, not new HelloWorld()
React.render(<HelloWorld />, document.getElementById("test"))
Example
jsx-in-depth
Or you can use React.createElement, like so
React.render(React.createElement(HelloWorld, null), document.getElementById("test"))
Example

Dynamically load JSX file in JavaScript

I am trying to implement a wrapper API file for a ReactJS component.
For example, /js/test.react.js
/** #jsx React.DOM */
var TESTCLASS = React.createClass({
render : function() {
return (
<div> Test </div>
);
}
});
I have written a wrapper JavaScript file for that:
var testClass = {
load: function () {
var script = document.createElement("script");
script.type = "text/jsx";
document.head.appendChild(script);
script.onload = function(){
React.render(
<TESTCLASS/>,
document.body)
};
script.src ="./js/test.react.js";
}
};
Then I can use the wrapper API JavaScript in a third-party HTML.
<html>
<head>
<title>Hello React</title>
<script src="http://fb.me/react-0.12.2.js"></script>
<script src="http://fb.me/JSXTransformer-0.12.2.js"></script>
<script src="http://code.jquery.com/jquery-1.10.0.min.js"></script>
<script type="text/jsx" src="test.js"></script>
</head>
<body>
<div id="content"></div>
<script>
testClass.load();
</script>
</body>
</html>
However, it seems to me /js/test.react.js cannot be dynamically loaded as pure JavaScript file. Can any expert explain to me the reason and provide a proper solution to write my wrapper API JavaScript file?
JSXTransformer*.js exports a global JSXTransformer object which has an exec() function, which transpiles JSX then eval()s the result.
You could try running JSXTransformer.exec() with the script's contents onload first.
Also, FYI, the #jsx pragma is no longer required as of React 0.12 :)

HTMl Import own WebComponent

In my index.html I import an external HTML file with an Template, Shadow DOM etc. A custom web Component.
// index.html
...
<script src="//cdnjs.cloudflare.com/ajax/libs/polymer/0.3.4/platform.js"></script>
<link rel="import" href="/html-components/userlogin-header.html" >
<head>
<body>
<userlogin-header username="Test User"userimage="http://domain.com/img.jpg"></userlogin-header>
...
And the other file userlogin-header.html:
// userlogin-header.html
<template id="userlogin-header">
<div class="imgbox">
<img src="" class="userimage">
</div>
<div class="userinfo">
<div class="name"><span class="username"></div>
</div>
</template>
<script>
var doc = this.document.currentScript.ownerDocument,
UserLoginProto = Object.create( HTMLElement.prototype );
UserLoginProto.createdCallback = function() {
var template = doc.querySelector( "#userlogin-header" ),
box = template.content.cloneNode( true );
this.shadow = this.createShadowRoot();
this.shadow.appendChild( box );
var username = this.shadow.querySelector( '.userinfo .username' );
username.innerHTML = ( this.getAttribute( 'username' ) || 'Unbekannt' );
var imageurl = this.shadow.querySelector( 'img.userimage' );
imageurl.src = 'https://secure.gravatar.com/avatar/' + this.getAttribute( 'userimage' ) + '1?s=40&d=http://s3-01.webmart.de/web/support_user.png';
};
var Xuserlogin = doc.registerElement( 'userlogin-header', { 'prototype' : UserLoginProto } );
</script>
The problem is that there is the following error on call index.html
Uncaught TypeError: Cannot read property 'content' of null
If I enable HTML Import in my Chrome everything works correctly. But then I disable this and use platform.js instead there is this error.
Is there any solution for this problem? I do not want to use the whole polymer framework.
This is a symptom of this caveat of the polyfill.
In a native HTML Imports, document.currentScript.ownerDocument
references the import document itself. In the polyfill use
document._currentScript.ownerDocument (note the underscore).
Once you change that, you also need to use document.registerElement instead of doc.registerElement. You want to register the element such that it's visible to the importing document, not the imported one.
var Xuserlogin = document.registerElement(...);
Here's a working plunk.

Categories