我一直在学习 React,我读到从返回的函数useEffect
是为了进行清理,而 React 在组件卸载时执行清理。
因此,我对其进行了一些试验,但在以下示例中发现,每次组件重新渲染时都会调用该函数,而不是仅在从 DOM 卸载时调用该函数,即每次组件重新渲染时都会调用该函数console.log("unmount");
。
这是为什么?
function Something({ setShow }) {
const [array, setArray] = useState([]);
const myRef = useRef(null);
useEffect(() => {
const id = setInterval(() => {
setArray(array.concat("hello"));
}, 3000);
myRef.current = id;
return () => {
console.log("unmount");
clearInterval(myRef.current);
};
}, [array]);
const unmount = () => {
setShow(false);
};
return (
<div>
{array.map((item, index) => {
return (
<p key={index}>
{Array(index + 1)
.fill(item)
.join("")}
</p>
);
})}
<button onClick={() => …
Run Code Online (Sandbox Code Playgroud) 我正在看一些关于 React Hooks 的教程,在教程中作者创建了一个useDropdown
用于渲染可重用下拉列表的钩子。代码是这样的
import React, { useState } from "react";
const useDropdown = (label, defaultState, options) => {
const [state, updateState] = useState(defaultState);
const id = `use-dropdown-${label.replace(" ", "").toLowerCase()}`;
const Dropdown = () => (
<label htmlFor={id}>
{label}
<select
id={id}
value={state}
onChange={e => updateState(e.target.value)}
onBlur={e => updateState(e.target.value)}
disabled={!options.length}
>
<option />
{options.map(item => (
<option key={item} value={item}>
{item}
</option>
))}
</select>
</label>
);
return [state, Dropdown, updateState];
};
export default useDropdown;
Run Code Online (Sandbox Code Playgroud)
他在这样的组件中使用了它
import React, { useState, useEffect …
Run Code Online (Sandbox Code Playgroud) 我最近了解到似乎有多种方法可以在网页上显示图像。
第一种方法是直接将 URL 分配给图像元素的 URL
const img = new Image();
img.onload = () => {
document.querySelector("#myImage").src = url;
};
img.onerror = () => {};
img.src = imageUrl;
Run Code Online (Sandbox Code Playgroud)
我最近学到的另一种方法是使用fetch
fetch(imageUrl)
.then((response)=>response.blob())
.then((blob)=>{
const objectUrl = URL.createObjectURL(blob)
document.querySelector("#myImage").src = objectUrl;
})
Run Code Online (Sandbox Code Playgroud)
我对这两种方法都有一些疑问:
我很熟悉,fetch
但我通常用它来获取 JSON。在我看来,第二种获取fetch
图像的方法就像我们通过 HTTP 获取该图像文件的原始二进制数据,而第一种方法是我们委托浏览器启动Get
获取该图像的请求。但从服务器的角度来看,在如何发送图像方面没有区别?我这样理解对吗?
在什么情况下我们应该优先选择一种方法而不是另一种?我觉得第二种方法比第一种方法会出现很多 CORS 问题,但不确定具体原因。
还有其他方法可以在网页上显示图像吗?当人们谈论图像时,我经常听说 Base64 编码/解码。response.blob()
base64与ie第二种方法有关吗?还是有所不同?如果是这样,有人可以给我一个使用 base64 显示图像的例子吗?
最后,我认为显示图像一直是我前端或 Web 开发知识中的一个漏洞。请随时推荐有关此主题的任何好的资源。
是否可以编写一个实用程序类型Number<T>
,它接受可以转换为数字的字符串文字类型,如果不能,则返回一个never
类型?
type Five = Number<'5'> // `Five` is of the type number 5
Run Code Online (Sandbox Code Playgroud)
我只是想先回答一下我为什么要这样做的问题:
我问这个问题的原因是我正在尝试编写一个Add
实用程序类型来添加数字
type createArray<Len, Ele, Arr extends Ele[] = []> = Arr['length'] extends Len ? Arr : createArray<Len, Ele, [Ele, ...Arr]>
type Add<A extends number, B extends number> = [...createArray<A, 1>, ...createArray<B, 1>]['length']
Run Code Online (Sandbox Code Playgroud)
现在它有效
type Five = Number<'5'> // `Five` is of the type number 5
Run Code Online (Sandbox Code Playgroud)
但它只接受number
类型。我想让它也不接受string
类型,这样它也可以工作type Answer = Add<'3','10'>
我从d.ts
API 文件中得到了这种类型
type EventConfigurations = {
Event1: {
Enabled?: boolean;
};
Event2: {
Enabled?: boolean;
};
Event3: {
Enabled?: boolean;
};
};
Run Code Online (Sandbox Code Playgroud)
现在我已经从该 API 调用的响应中返回了这些数据
const eventConfigurations: EventConfigurations = {
Event1: { Enabled: true },
Event2: { Enabled: false },
Event3: { Enabled: true }
};
Run Code Online (Sandbox Code Playgroud)
现在我想将数据映射到
enum EventDesc {
Event1 = "XXX",
Event2 = "YYY",
Event3 = "ZZZ"
}
type MyEvent = {
eventDesc: EventDesc;
topic: EventTopic;
};
const eventConfigurations: EventConfigurations = {
Event1: { Enabled: true …
Run Code Online (Sandbox Code Playgroud) 首先,您将看到的代码片段是一个人为的示例。我只是好奇为什么打字不起作用。
interface MyState {
a: boolean;
b: number;
}
const defaultState: MyState = {
a: false,
b: 1
};
const keys = Object.keys(defaultState) as Array<keyof MyState>;
export default function App() {
const [myState, setMyState] = React.useState<MyState>(defaultState);
React.useEffect(() => {
keys.forEach((key) => {
setMyState((prev) => ({
...prev,
[key]: "lol". // should've given an error but it didn't
}));
});
}, []);
Run Code Online (Sandbox Code Playgroud)
所以我有一个defaultState
和它在组件外部定义的键列表。在 useEffect 中,我使用密钥来更新状态(现在它只是将每个值更改为“lol”)。我传递了一个回调作为 中的更新程序,setMyState
它返回的应该是新状态。但是在这里我将值设为字符串,这违反了我拥有的接口MyState
。
我想知道为什么它没有触发错误
这是一个现场演示:https : //codesandbox.io/s/sweet-dewdney-u83id?file=/ src/ App.tsx
没有反应的最小例子:游乐场
因此,最近我一直在阅读有关Javascript承诺的教程。
这是一个示例,用于解释宏任务队列(即事件循环)和微任务队列。
let promise = Promise.reject(new Error("Promise Failed!"));
promise.catch(err => alert('caught'));
// no error, all quiet
window.addEventListener('unhandledrejection', event => alert(event.reason));
Run Code Online (Sandbox Code Playgroud)
它说,因为promise.catch
捕获错误,所以最后一行,所以事件处理程序永远不会运行。我能理解 但是随后他稍微调整了这个示例。
let promise = Promise.reject(new Error("Promise Failed!"));
setTimeout(() => promise.catch(err => alert('caught')));
// Error: Promise Failed!
window.addEventListener('unhandledrejection', event => alert(event.reason));
Run Code Online (Sandbox Code Playgroud)
这一次,他说,事件处理程序会首先运行,并捕获错误并经过这个promise.catch
最终捕获错误。
对于第二个示例,我不了解的是,为什么事件处理程序在promise.catch
?之前运行?
我的理解是
setTimeout
,将其放在宏任务队列中,然后,因为微任务比宏任务具有更高的优先级。我们首先兑现诺言。之后,我们将宏任务队列中的第一个任务出队setTimeout
。因此,根据我的理解,该错误应由内部函数捕获setTimeout
。
请纠正我。
我正在用 React 编写 TypeScript。该项目是用 CRA 生成的。我使用react-app
了.eslintrc.json
. 不过我决定使用,eslint-config-airbnb
所以我添加了它并更改了我的.eslintrc.json
{
"extends": [
"airbnb",
]
}
Run Code Online (Sandbox Code Playgroud)
突然我从 ESLint 得到了关于enum
我在代码库中使用的类型的解析错误
`Parsing error: The keyword 'enum' is reserved eslint`
Run Code Online (Sandbox Code Playgroud)
我用谷歌搜索但找不到答案。尝试添加一些额外的配置,例如
"parserOptions": {
"ecmaVersion": 7,
}
Run Code Online (Sandbox Code Playgroud)
但这并不能解决问题
typescript reactjs eslint eslint-config-airbnb typescript-eslint
我正在学习如何使用@babel/preset-env
我们的客户所需的浏览器polyfills。我的理解是,如果访问网站的客户端是目标环境之一,babel 就会发送polyfills。似乎有两种方法可以指定目标环境: 1. browserlist 2.targets
选项{ "presets": [["@babel/preset-env", { "targets": "defaults" }]] }
但这里有几点我不太明白:
core-js
. 添加 polyfill 似乎是一个构建时过程。我不太明白的是 babel 实际上是如何选择客户端需要的 polyfills 的 - babel 是一次性导入所有的 polyfills 并且仅在需要时在运行时应用它还是仅在构建时导入所需的 polyfills?如果 Babel 没有选择要应用的 polyfill,那么在运行时会如何发生这种情况?有人可以向我详细解释一下吗?targets
设置目标环境与使用browserlist
设置目标环境有什么区别?此外,我对 的默认查询感到困惑targets
。在 babel 的文档上它说因此,preset-env 的行为与 browserslist 不同:当 Babel 或 browserslist 配置中没有找到目标时,它不会使用默认查询。如果您想使用默认查询,则需要显式地将其作为目标传递:
因此,仅拥有{ "presets": ["@babel/preset-env"] }
不会给我们默认查询,我们必须显式地将目标设置为默认值,如"presets": [["@babel/preset-env", { "targets": "defaults" }]]
?
"@babel/preset-env"
但没有browserlist …
function Foo({
children,
...rest
}: {
children: React.ReactNode;
/*rest: how do I type `rest`? */
}) {
return (
<span style={{ background: "red" }} {...rest}>
{children}
</span>
);
}
export default function App() {
return (
<div className="App">
<Foo style={{ background: "blue" }}>Hello CodeSandbox</Foo>
</div>
);
}
Run Code Online (Sandbox Code Playgroud)
这是演示:https://codesandbox.io/s/how-to-type-rest-huv2z? file=/src/App.tsx:50-412
Foo
用于覆盖span
接受的 props。我该如何rest
输入Foo
?
javascript ×7
reactjs ×5
typescript ×5
react-hooks ×2
babeljs ×1
base64 ×1
eslint ×1
event-loop ×1
fetch-api ×1
html ×1
polyfills ×1
use-effect ×1