闽公网安备 35020302035485号
{} === {} // false
因此,高级 React 开发者需要非常了解 React 的默认优化机制,让 props 的比较不发生,因为一旦发生,那么结果必定是 false。<StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</StrictMode>
遵循严格模式的规范,我们的组件更容易符合 React Compiler 的优化规则。我们可以使用如下方式首先检测代码库是否兼容。在项目根目录下执行如下指令。npx react-compiler-healthcheck该脚本主要用于检测

const ReactCompilerConfig = {
sources: (filename) => {
return filename.indexOf('src/path/to/dir') !== -1;
},
};
React Compiler 还支持对应的 eslint 插件。该插件可以独立运行。不用非得与 Compiler 一起运行。npm i eslint-plugin-react-compiler然后在 eslint 的配置中添加
module.exports = {
plugins: [
'eslint-plugin-react-compiler',
],
rules: {
'react-compiler/react-compiler': 2,
},
}
Compiler 目前结合 Babel 插件一起使用,因此,我们首先需要在项目中引入该插件npm i babel-plugin-react-compiler然后,在不同的项目中,有不同的配置。
module.exports = function () {
return {
plugins: [
['babel-plugin-react-compiler', ReactCompilerConfig], // must run first!
// ...
],
};
};
注意,该插件应该在其他 Babel 插件之前运行。
在 vite 中使用
首先,我们需要安装 vite-plugin-react,注意不用搞错了,群里有的同学使用了 vite-plugin-react-swc 结果搞了很久没配置成功。然后在 vite.config.js 中,添加如下配置export default defineConfig(() => {
return {
plugins: [
react({
babel: {
plugins: [
["babel-plugin-react-compiler", ReactCompilerConfig],
],
},
}),
],
// ...
};
});
在 Next.js 中使用npm i vite-plugin-babel
// vite.config.js
import babel from "vite-plugin-babel";
// 堆代码 duidaima.com
const ReactCompilerConfig = { /* ... */ };
export default defineConfig({
plugins: [
remix({ /* ... */}),
babel({
filter: /\.[jt]sx?$/,
babelConfig: {
presets: ["@babel/preset-typescript"], // if you use TypeScript
plugins: [
["babel-plugin-react-compiler", ReactCompilerConfig],
],
},
}),
],
});
在 Webpack 中使用const ReactCompilerConfig = { /* ... */ };
const BabelPluginReactCompiler = require('babel-plugin-react-compiler');
function reactCompilerLoader(sourceCode, sourceMap) {
// ...
const result = transformSync(sourceCode, {
// ...
plugins: [
[BabelPluginReactCompiler, ReactCompilerConfig],
],
// ...
});
if (result === null) {
this.callback(
Error(
`Failed to transform "${options.filename}"`
)
);
return;
}
this.callback(
null,
result.code
result.map === null ? undefined : result.map
);
}
module.exports = reactCompilerLoader;
我们可以在 React 官方了解到更多关于 React Compiler 的介绍与注意事项。具体地址如下:https://react.dev/learn/react-compiler
<script src="http://localhost:8097"></script>

function Index() {
const [counter, setCounter] = useState(0)
function p() {
console.log('函数执行 ')
}
return (
<div>
<button onClick={() => setCounter(counter + 1)}>
点击修改 counter:{counter}
</button>
<Children a={1} b={2} c={p} />
</div>
)
}
我们先来分析一下这段代码。首先,在父组件中,我们设计了一个数字递增的状态。当点击发生时,状态递增。此时父组件会重新 render。因此,在以往的逻辑中,子组件 Children 由于没有使用任何优化手段,因此,在父组件重新渲染时,子组件由于 props 的比较结果为 false,也会重新执行。并且其中一个 props 属性还是一个引用对象,因此我们需要使用 useCallback + memo 才能确保子组件 Children 不会冗余 re-render。
import {use} from 'react'
import {Context} from './context'
export default function Card() {
const value = use(Context)
console.log('xxxxx context')
return (
<>
<div className='_06_card'>
<div className="title">Canary</div>
<p>The test page</p>
</div>
</>
)
}
理想情况是这种情况可以不用发生 re-render。因此总体来说,Compiler 目前确实还不能完全信任。也有可能我还没掌握正确的姿势,还需要对他有更进一步的了解才可以。不过值得高兴的是,新项目可以放心使用 Compiler,因为运行结果我们都能实时感知、调试、调整,能最大程度的避免问题的出现。
