我正在尝试在独立的UMD环境中使用React Hooks。我遇到以下错误
未经公开的违规行为:缩小反应错误#307;
错误将我指向https://reactjs.org/docs/error-decoder.html/?invariant=307
在这种情况下如何使用钩子?以下是我的代码:
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.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>
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')
);
您已经错误地渲染了Counter
组件,您需要在ReactDOM.render
中使用React.createElement
渲染它。另外,即使您通过buttonCounter和对反应进行反应,该应用程序也可以正常工作。
return React.createElement(
'div',
{className: 'counter'},
CounterText({count: count}),
ButtonCounter({clickHandler: updateCount})
);
您更好地通过创建它们的react元素来传递子元素,从而可以对其进行优化。当CounterText
和ButtonCounter
还包含来自React的一些逻辑时,这很重要。
您也可以将状态和处理程序传递给这些组件作为工作应用程序的道具
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.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>
这里的几个问题,您不应该调用您的组件:
Counter()
React将单独进行(懒惰评估),因此您也需要用createElement
包装它。
例如:
ReactDOM.render(
React.createElement(Counter),
document.getElementById('root')
);
另一件事,您并没有真正使用count
和setCount
:
return React.createElement(
'div',
{className: 'counter'},
CounterText({count: 0}),
ButtonCounter({})
);
这是一个正在运行的示例:
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.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>
在您的应用中添加babel独立。然后,您可以使用JSX和所有其他内容,您还需要执行此操作
<script type="text/babel" src="App.js" async defer></script>
功能组件在使用钩子的情况下直接调用。createElement
应用于所有组件:
return React.createElement(
'div',
{className: 'counter'},
React.createElement(CounterText, {count: 0}),
React.createElement(ButtonCounter)
);