xia*_*x48 2 jsx typescript reactjs react-hooks
当将 JSX 版本的 React Hooks API演示翻译成没有 JSX 的版本时,遵循React-without-jsx,我得到了以下代码
import React, { useState } from 'react';
import ReactDOM from 'react-dom';
export function test() {
ReactDOM.render(Count(), document.getElementById('main'));
}
export function Count() {
const e = React.createElement;
const [count, setCount] = useState(0);
const button = e('button', {
onClick: () => {
setCount(count + 1);
},
});
return e('div', null, e('p', `You clicked ${count} times`), button);
}
Run Code Online (Sandbox Code Playgroud)
但是,当在浏览器中运行此代码时,出现以下错误
react.development.js:1551 Uncaught Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
See https://reactjs.org/warnings/invalid-hook-call-warning.html for tips about how to debug and fix this problem.
at resolveDispatcher (react.development.js:1551)
at Object.useState (react.development.js:1582)
at Count (Count.ts:10)
at Object.test (Count.ts:5)
at main (index.ts:4)
at Object../src/index.ts (index.ts:6)
at __webpack_require__ (bootstrap:19)
at bootstrap:83
at bootstrap:83
resolveDispatcher @ react.development.js:1551
useState @ react.development.js:1582
Count @ Count.ts:9
test @ Count.ts:4
main @ index.ts:3
./src/index.ts @ index.ts:6
__webpack_require__ @ bootstrap:18
Run Code Online (Sandbox Code Playgroud)
如果使用 JSX,上面的例子就可以正常工作。
所有功能组件的示例似乎都是基于 JSX 的。那么是否可以在没有 JSX 的情况下使用 React Hook 呢?如果可以的话,我们怎样才能做到呢?
编辑更新:上面的代码仍然有错误(如以下编辑所述)。
这
e('p', `You clicked ${count} times`)
Run Code Online (Sandbox Code Playgroud)
应该
e('p', null, `You clicked ${count} times`)
Run Code Online (Sandbox Code Playgroud)
的第二个参数createElement应该是 props。
按照@qxg 的说明进行编辑。
在渲染过程中,我没有使用React.createElement,通过修改代码
import React, { useState } from 'react';
import ReactDOM from 'react-dom';
export function test() {
ReactDOM.render(React.createElement(Count), document.getElementById('main'));
}
// ... Same code for Count as above
Run Code Online (Sandbox Code Playgroud)
函数组件外部调用 Hooks API 错误已解决!
但是,出现了新的错误,例如:
Warning: Invalid attribute name: `0` react-dom.development.js:82
in p (created by Count)
in div (created by Count)
in Count
Warning: Invalid attribute name: `1` react-dom.development.js:82
in p (created by Count)
in div (created by Count)
in Count
Run Code Online (Sandbox Code Playgroud)
很多像上面这样的错误,以
Warning: Invalid attribute name: `18` react-dom.development.js:82
in p (created by Count)
in div (created by Count)
in Count
Run Code Online (Sandbox Code Playgroud)
页面呈现为
<div>
<p></p>
<button></button>
</div>
Run Code Online (Sandbox Code Playgroud)
因此只有空元素,没有文本。对于这个问题有什么建议吗?
ps我不确定是否存在typescript/webpack的配置错误,所以我将它们发布在这里。
ts.config.json
{
"compilerOptions": {
"target": "es5" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */,
"module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */,
"lib": [
"DOM",
"DOM.Iterable",
"ESNext"
] /* Specify library files to be included in the compilation. */,
"jsx": "react" /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */,
"sourceMap": true /* Generates corresponding '.map' file. */,
"outDir": "./dist" /* Redirect output structure to the directory. */,
"strict": true /* Enable all strict type-checking options. */,
"noImplicitReturns": true /* Report error when not all code paths in function return a value. */,
"noFallthroughCasesInSwitch": true /* Report errors for fallthrough cases in switch statement. */,
"esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */,
"skipLibCheck": true /* Skip type checking of declaration files. */,
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
}
}
Run Code Online (Sandbox Code Playgroud)
webpack.config.js
const path = require('path');
module.exports = {
mode: 'development',
entry: './src/index.ts',
// Enable sourcemaps for debugging webpack's output.
devtool: 'source-map',
resolve: {
// Add '.ts' and '.tsx' as resolvable extensions.
extensions: ['.ts', '.tsx'],
},
module: {
rules: [
{
test: /\.ts(x?)$/,
exclude: /node_modules/,
use: [
{
loader: 'ts-loader',
},
],
},
// All output '.js' files will have any sourcemaps re-processed by 'source-map-loader'.
{
enforce: 'pre',
test: /\.js$/,
loader: 'source-map-loader',
},
],
},
externals: {
react: 'React',
'react-dom': 'ReactDOM',
},
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
},
};
Run Code Online (Sandbox Code Playgroud)
索引.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Hello React!</title>
</head>
<body>
<div id="main"></div>
<script src="./node_modules/react/umd/react.development.js"></script>
<script src="./node_modules/react-dom/umd/react-dom.development.js"></script>
<!-- Main -->
<script src="./dist/bundle.js"></script>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
您手动将 jsx 转换为 React.creatElement 但也忘记转换顶级元素。
ReactDOM.render(React.createElement(Count), document.getElementById('main'));
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3188 次 |
| 最近记录: |