考虑下面的片段。在 React 18 中,count每次渲染都会在控制台上打印两次,但在 React 17 中只打印一次。
反应 18 示例:
function App() {
const [count, setCount] = React.useState(0);
console.log(count);
return <button onClick={() => setCount(count + 1)}>{count}</button>;
}
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);Run Code Online (Sandbox Code Playgroud)
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<div id="root"></div>Run Code Online (Sandbox Code Playgroud)
反应 17 示例
function App() {
const [count, setCount] = React.useState(0);
console.log(count);
return <button onClick={() => setCount(count + 1)}>{count}</button>;
}
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById("root")
);Run Code Online (Sandbox Code Playgroud)
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script> …Run Code Online (Sandbox Code Playgroud)在下面的代码片段中,我无法使用typeof运算符来区分联合类型。
function f(arg: { status: number; one: boolean } | { status: string; two: boolean }) {
if (typeof arg.status === "number") {
return arg // arg is still of the union type and is not narrowed
} else {
return arg // similar here
}
}
Run Code Online (Sandbox Code Playgroud)
但如果status改为某种文字类型,那么联合体就可以被区分。
function f(arg: { status: "one"; one: boolean } | { status: "two"; two: boolean }) {
if (arg.status=== "one") {
return arg // here arg is of type …Run Code Online (Sandbox Code Playgroud) 考虑以下片段:
type Add = (a: number | string, b: number | string) => number | string;
function hof(cb: Add) {}
const addNum = (a: number, b: number): number => a + b;
const addStr = (a: string, b: string): string => a + b;
// @ts-expect-error
hof(addNum);
// @ts-expect-error
hof(addStr);
Run Code Online (Sandbox Code Playgroud)
为什么我们不能将addNum和addStr函数传递给hof,IMO 他们的调用签名应该与hof预期兼容,但实际上并非如此。
如果它们的类型不兼容,那么为什么以下代码片段中的重载签名不会抱怨?
function add(a: number, b: number): number;
function add(a: string, b: string): string;
function add(a: number | string, b: number …Run Code Online (Sandbox Code Playgroud) 以下是我想测试的自定义挂钩:
import { useEffect, useState } from "react";
export const useAlert = () => {
const [alert, setAlert] = useState(null);
useEffect(() => {
let timerId = setTimeout(() => {
console.log("Timeout, removing alert from DOM");
setAlert(null);
}, 200);
return () => clearTimeout(timerId);
}, [alert]);
return {
renderAlert: alert ? alert : null,
setAlert,
};
};
Run Code Online (Sandbox Code Playgroud)
它只是允许组件设置警报并在 300 毫秒后自动清除警报。
这是对上述钩子的工作测试
import { render, screen, waitFor } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { useAlert } from "../components/useAlert";
// jest.useFakeTimers();
function FakeComponent() …Run Code Online (Sandbox Code Playgroud)