最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to use React Hooks in React standalone? - Stack Overflow

programmeradmin2浏览0评论

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
Add a ment  | 

4 Answers 4

Reset to default 4

You 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)
);
发布评论

评论列表(0)

  1. 暂无评论