I am trying to use React Hooks in a standalone UMD environment. I am getting the below error
Uncaught Invariant Violation: Minified React error #307;
The error is pointing me to .html/?invariant=307
How do i use Hooks in this case? Below is my code:
index.html
<!DOCTYPE html>
<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]> <html class="no-js lt-ie9"> <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js"> <!--<![endif]-->
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>React Hooks</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="">
</head>
<body>
<!--[if lt IE 7]>
<p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="#">upgrade your browser</a> to improve your experience.</p>
<![endif]-->
<div id="root"></div>
<script src=".8.4/umd/react.production.min.js"></script>
<script src=".8.4/umd/react-dom.production.min.js"></script>
<script src="App.js" async defer></script>
</body>
</html>
App.js
var CounterText = function(props) {
return React.createElement(
'div',
null,
`You clicked ${props.count} times!`
);
}
var ButtonCounter = function(props) {
return React.createElement(
'button',
{className: 'btn', onClick: props.clickHandler},
`Click Me!`
);
}
var Counter = function() {
var state = React.useState(0);
var count = state[0];
var setCount = state[1];
return React.createElement(
'div',
{className: 'counter'},
CounterText({count: 0}),
ButtonCounter({})
);
}
ReactDOM.render(
Counter(),
document.getElementById('root')
);
I am trying to use React Hooks in a standalone UMD environment. I am getting the below error
Uncaught Invariant Violation: Minified React error #307;
The error is pointing me to https://reactjs/docs/error-decoder.html/?invariant=307
How do i use Hooks in this case? Below is my code:
index.html
<!DOCTYPE html>
<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]> <html class="no-js lt-ie9"> <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js"> <!--<![endif]-->
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>React Hooks</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="">
</head>
<body>
<!--[if lt IE 7]>
<p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="#">upgrade your browser</a> to improve your experience.</p>
<![endif]-->
<div id="root"></div>
<script src="https://cdnjs.cloudflare./ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare./ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<script src="App.js" async defer></script>
</body>
</html>
App.js
var CounterText = function(props) {
return React.createElement(
'div',
null,
`You clicked ${props.count} times!`
);
}
var ButtonCounter = function(props) {
return React.createElement(
'button',
{className: 'btn', onClick: props.clickHandler},
`Click Me!`
);
}
var Counter = function() {
var state = React.useState(0);
var count = state[0];
var setCount = state[1];
return React.createElement(
'div',
{className: 'counter'},
CounterText({count: 0}),
ButtonCounter({})
);
}
ReactDOM.render(
Counter(),
document.getElementById('root')
);
Share
Improve this question
asked Mar 12, 2019 at 11:48
VishwaKumarVishwaKumar
3,4338 gold badges47 silver badges72 bronze badges
4 Answers
Reset to default 4You have rendered the Counter
ponent incorrectly, you need to render it using React.createElement
within ReactDOM.render
. Also, even though the app will work even if you pass ButtonCounter and CounterText to React.createElement like
return React.createElement(
'div',
{className: 'counter'},
CounterText({count: count}),
ButtonCounter({clickHandler: updateCount})
);
its better that you pass on the child elements by creating React element ot of them so that react can optimize on it. This is important specifically when CounterText
and ButtonCounter
also contains some logic from React.
Also you can pass down state and handlers to these ponents as props for a working application
var CounterText = function(props) {
return React.createElement(
'div',
null,
`You clicked ${props.count} times!`
);
}
var ButtonCounter = function(props) {
return React.createElement(
'button',
{className: 'btn', onClick: props.clickHandler},
`Click Me!`
);
}
var Counter = function() {
var state = React.useState(0);
var count = state[0];
var setCount = state[1];
var updateCount = () => {
setCount(count => count + 1)
}
return React.createElement(
'div',
{className: 'counter'},
React.createElement(CounterText, {count: count}),
React.createElement(ButtonCounter,{clickHandler: updateCount})
);
}
ReactDOM.render(
React.createElement(Counter),
document.getElementById('root')
);
<!DOCTYPE html>
<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]> <html class="no-js lt-ie9"> <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js"> <!--<![endif]-->
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>React Hooks</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="">
</head>
<body>
<!--[if lt IE 7]>
<p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="#">upgrade your browser</a> to improve your experience.</p>
<![endif]-->
<div id="root"></div>
<script src="https://cdnjs.cloudflare./ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare./ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<script src="App.js" async defer></script>
</body>
</html>
Couple of issues here, You shouldn't invoke your ponents like:
Counter()
React will do it by itself (lazy evaluation), so you need to wrap it with createElement
as well.
For example:
ReactDOM.render(
React.createElement(Counter),
document.getElementById('root')
);
Another thing, you are not really using the count
and setCount
:
return React.createElement(
'div',
{className: 'counter'},
CounterText({count: 0}),
ButtonCounter({})
);
Here is a running example:
var CounterText = function(props) {
return React.createElement(
'div',
null,
`You clicked ${props.count} times!`
);
}
var ButtonCounter = function(props) {
return React.createElement(
'button', {
className: 'btn',
onClick: props.clickHandler
},
`Click Me!`
);
}
var Counter = function() {
var state = React.useState(0);
var count = state[0];
var setCount = state[1];
return React.createElement(
'div', {
className: 'counter'
},
React.createElement(CounterText,{
count:count
}),
React.createElement(ButtonCounter,{clickHandler: () => setCount(c => c + 1)})
);
}
ReactDOM.render(
React.createElement(Counter),
document.getElementById('root')
);
<script src="https://cdnjs.cloudflare./ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare./ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="root"></div>
<script src="App.js" async defer></script>
add babel standalone in your app. and then you can use jsx and all other stuff, also you need to do this
<script type="text/babel" src="App.js" async defer></script>
Functional ponents cannot be called directly in case they use hooks. createElement
should be used for all ponents:
return React.createElement(
'div',
{className: 'counter'},
React.createElement(CounterText, {count: 0}),
React.createElement(ButtonCounter)
);