2
votes

Comment utiliser React Hooks dans React autonome?

J'essaye d'utiliser React Hooks dans un environnement UMD autonome. J'obtiens l'erreur ci-dessous

Violation invariante non interceptée: erreur de réaction réduite n ° 307;

L'erreur me dirige vers https: // reactjs.org/docs/error-decoder.html/?invariant=307

Comment utiliser les Hooks dans ce cas? Voici mon code:

index.html

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')
);

App.js

<!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.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
        <script src="App.js" async defer></script>
    </body>
</html>


0 commentaires

4 Réponses :


0
votes

ajoutez babel standalone dans votre application. et ensuite vous pouvez utiliser jsx et toutes les autres choses, vous devez également le faire

<script type="text/babel" src="App.js" async defer></script>


0 commentaires

0
votes

Les composants fonctionnels ne peuvent pas être appelés directement s'ils utilisent des hooks. createElement doit être utilisé pour tous les composants:

return React.createElement(
    'div',
    {className: 'counter'},
    React.createElement(CounterText, {count: 0}),
    React.createElement(ButtonCounter)
);


0 commentaires

4
votes

Vous avez mal rendu le composant Counter , vous devez le rendre en utilisant React.createElement dans ReactDOM.render . De plus, même si l'application fonctionnera même si vous transmettez ButtonCounter et CounterText à React.createElement comme

<!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.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
        <script src="App.js" async defer></script>
    </body>
</html>

, il vaut mieux que vous transmettiez les éléments enfants en créant un élément React pour qu'ils réagissent peut optimiser dessus. Ceci est particulièrement important lorsque CounterText et ButtonCounter contiennent également une logique de React.

Vous pouvez également transmettre l'état et les gestionnaires à ces composants comme accessoires pour une application fonctionnelle

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')
);
return React.createElement(
    'div',
    {className: 'counter'},
    CounterText({count: count}),
    ButtonCounter({clickHandler: updateCount})
);


0 commentaires

3
votes

Quelques problèmes ici, vous ne devriez pas invoquer vos composants comme:

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/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>

React le fera tout seul (évaluation paresseuse), vous devez donc l'envelopper avec createElement également.

Par exemple:

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')
);

Autre chose, vous n'utilisez pas vraiment le code count et setCount >:

return React.createElement(
        'div',
        {className: 'counter'},
        CounterText({count: 0}),
        ButtonCounter({})
    );

Voici un exemple en cours d'exécution:

ReactDOM.render(
  React.createElement(Counter),
  document.getElementById('root')
);
Counter()


0 commentaires