我的场景很少,我想了解渲染和性能方面的差异。
下面显示的示例是一个简单的函数,但也请考虑一个更复杂的函数以及异步函数。
场景 1:定义函数并在 useEffect 中调用它。
useEffect(() => {
function getBooks() {
console.log('I get books!');
}
getBooks();
}, []);
Run Code Online (Sandbox Code Playgroud)
场景 2:在 UseEffect 外部定义函数并在其内部调用它。
function getBooks() {
console.log('I get books!');
}
useEffect(() => {
getBooks();
}, []);
Run Code Online (Sandbox Code Playgroud)
场景 3:使用 useCallback 在 UseEffect 外部定义函数并在其内部调用它。
const getBooks = useCallback(() => {
console.log('I get books!');
}, []);
useEffect(() => {
getBooks();
}, []);
Run Code Online (Sandbox Code Playgroud)
场景 4:使用 useCallback 在 UseEffect 中定义一个函数,并在 UseEffect 中调用它。
useEffect(() => {
const getBooks = useCallback(() => { …Run Code Online (Sandbox Code Playgroud) 我有一个组件,它通过addEventListener和在多个地方使用事件侦听器removeEventListener。使用像这样的组件方法是不够的onMouseMove因为我还需要检测组件外部的事件。
我在组件中使用钩子,其中几个在末尾有依赖数组,特别是useCallback(eventFunction, dependencies)与侦听器一起使用的事件函数。依赖项通常是使用声明的有状态变量useState.
据我所知,函数的身份在 中很重要add/remove EventListener,因此如果函数在两者之间发生变化,它就不起作用。起初我尝试管理钩子,以便事件函数不会改变add和remove但是随着函数对状态的依赖,这很快变得笨拙。
所以最后我想出了以下模式:由于 setter 函数(到 的第二个输入参数useState)获取当前状态作为参数,我可以拥有在第一次渲染后永远不会改变的事件函数(我们是否仍然称此挂载?) 但仍然可以访问最新的有状态变量。一个例子:
import React, { useCallback, useEffect, useState } from 'react';
const Component = () => {
const [state, setState] = useState(null);
const handleMouseMove = useCallback(() => {
setState((currentState) => {
// ... do something that involves currentState ...
return currentState;
});
}, []);
useEffect(() => {
window.addEventListener('mousemove', handleMouseMove);
return () => { …Run Code Online (Sandbox Code Playgroud) 我已经构建了一个自定义的自定义帖子挂钩,它返回 API 响应和 API 帖子。我正在使用useCallback钩子来设置Response state
出错的地方是钩子Package prop内部没有更新useCallback。
当我Package在useCallback钩子外登录时,我会在属性内获得正确的数据。但是,当我Package prop在useCallback钩子内部登录时,的值Package不会改变。
无论我按下按钮多少次
我尝试创建一个state每次Package prop更新时都会更新的订单,但是每当我设置Package为 中的一个值时,scope我都会得到一个无限循环。
我阿洛斯加Package进scope了的useCallback钩
例子
React.useEffect(() => {
setOrder(Package);
}, [Package]);
Run Code Online (Sandbox Code Playgroud)
我期望发生的是,每当我调用我的自定义usePostOrder钩子时Package,里面的useCallback值总是与最新传递的 prop 保持同步。
自定义挂钩
/**
* custom post hook that returns the API response and the API post …Run Code Online (Sandbox Code Playgroud) 根据我从 React 文档和网络上其他材料中了解到的, useCallback 用于通过确保将回调的记忆版本传递给子组件来避免重新渲染子组件,因此子组件的引用属性保持相同。但只有当我在子组件上使用 React.memo 时,所有这些才有效。如果没有 React.memo,子组件无论如何都会重新渲染。我的问题是在这种情况下 useCallback 有什么用处,即没有将 React.memo 应用于子组件。useCallback 还有哪些其他好处?
我的回调在一次又一次调用后返回相同的状态
我是反应类中反应钩子的新手,我本可以使用 shouldcomponentupdate 并且可以解决这个问题
但是 usecallback 钩子中没有参数
import React, {
useLayoutEffect,
useState,
useCallback,
useEffect,
} from "react";
import { StyleSheet, Text, View, Platform, YellowBox } from "react-native";
import { HeaderButtons, Item } from "react-navigation-header-buttons";
import HeaderButton from "../components/HeaderButton";
import { Switch } from "react-native-paper";
import Colors from "../constants/Colors";
//check use callback value first
YellowBox.ignoreWarnings([
"Non-serializable values were found in the navigation state",
]);
const FilterSwitch = ({ label, state, onChange }) => (
<View style={styles.filterContainer}>
<Text>{label}</Text>
<Switch
value={state}
trackColor={{ true: …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用 Typescript 和 useCallback,但出现此错误
Expected 0 arguments, but got 1
这是我的代码
const searchFriends = useCallback(() => (filterValue: string): void => {
if (dataState.length <= INITIAL_FRIENDS_API_REQUEST) fetchAllFriends()
const filterValueInsensitive = filterValue.toLowerCase()
const filtered = dataState.filter((friend: Friends) => {
return friend.displayName?.toLowerCase().includes(filterValueInsensitive)
})
setFriendsDisplayState(filtered)
}, [dataState,fetchAllFriends])
const handleChangeSearchInput = (
e: React.ChangeEvent<HTMLInputElement>
): void => searchFriends(e.currentTarget.value) // ERROR here "Expected 0 arguments, but got 1"
Run Code Online (Sandbox Code Playgroud)
知道如何修复它吗?
这是我在 React js 中的代码的一部分:
export default function Registration() {
const [email, setEmail] = useState(null);
const [password, setPassword] = useState(null);
const [passwordRepeat, setPasswordRepeat] = useState(null);
const [isFieldsOK, setFieldsOK] = useState(false);
useEffect(() => {
if (checkFieldsOK()) {
setFieldsOK(true);
} else {
setFieldsOK(false);
}
}, [checkFieldsOK])
const checkFieldsOK = () => {
return (isEmail(email) && isValidPassword(password) && passwordRepeat === password);
}
}
Run Code Online (Sandbox Code Playgroud)
我有 isFieldsOK 状态,它告诉我我的字段是否有效,并且我希望它“侦听”注册功能中的每个更改。运行此命令后,我收到此警告:
The 'checkFieldsOK' function makes the dependencies of useEffect Hook (at line 34) change on every render. Move it …Run Code Online (Sandbox Code Playgroud) 我正在尝试创建一个基于useContext 的自定义挂钩useFocus以仅将焦点设置在我选择的组件上。它的工作,但其他组件正在呈现,即使我使用useCallback作为我的 useFocus 自定义挂钩返回的函数。
我只想重新渲染焦点变化的组件。
我知道如果代码很快,重新渲染可能是一个小问题,但我不明白为什么要重新渲染。你能给我一些解释或解决办法吗?
预期结果:
单击“设置焦点”按钮时,我期望得到:
1 个 A/B/D 渲染
2 个 C/E 渲染
谢谢。
这是我的代码:
import React, { createContext, useCallback, useContext, useState } from "react";
import "./styles.css";
const StepContext = createContext({});
//This is just to display number or render for each Items
function useRenderCounter() {
const ref = React.useRef();
React.useEffect(() => {
ref.current.textContent = Number(ref.current.textContent || "0") + 1;
});
return (
<span
style={{
backgroundColor: "#ccc",
borderRadius: 4,
padding: "2px 4px", …Run Code Online (Sandbox Code Playgroud) 我对React 中的useMemo和useCallback钩子相当陌生,我有点困惑为什么我的函数仍然继续重新渲染,即使我检查的变量保持不变。目前我正在尝试构建一个谷歌地图,允许用户打开和关闭地图上显示的某些标记。我的功能组件应该只需要在加载时渲染这些标记,然后在加载后记住它们,因为它们只是在之后打开/关闭。现在我理解这样的钩子只进行浅层比较的概念,但我正在比较布尔值,我认为这些钩子能够理解这些值。
这是我当前的地图文件:
// constants are above
function Map() {
const {isLoaded} = useJsApiLoader({
googleMapsApiKey: env.GOOGLE_MAPS_API.API_KEY,
libraries: libs
})
const [map, setMap] = useState(null);
const [places,setPlaces] = useState([]);
const [places2,setPlaces2] = useState([]);
const [heatMap,setHeatMap] = useState([]);
const [fetchingData, setFetchingData] = useState(true);
const [showPlaces,setShowPlaces] = useState(true);
const [showPlaces2,setShowPlaces2] = useState(false);
const [showHeatMap,setShowHeatMap] = useState(false);
useEffect(() => {
let mounted = true;
if(mounted){
socket.emit('getMapAnalytics', ([heatmap,places,places2]) => {
console.log({heatmap})
setPlaces(places);
setPlaces2(places2);
setHeatMap(heatmap);
setFetchingData(false);
});
}
return () => { …Run Code Online (Sandbox Code Playgroud) 据我了解,两者之间的区别在于,如果返回函数、对象或数组,则使用 useCallback,而返回原语时则使用 useMemo。但我正在查找去抖(这是文章: https: //dmitripavlutin.com/react-throttle-debounce/,它说 useMemo 将是一个更好的解决方案。使用 useCallback
import { useState, useCallback } from 'react';
import debounce from 'lodash.debounce';
export function FilterList({ names }) {
const [query, setQuery] = useState("");
let filteredNames = names;
if (query !== "") {
filteredNames = names.filter((name) => {
return name.toLowerCase().includes(query.toLowerCase());
});
}
const changeHandler = event => {
setQuery(event.target.value);
};
const debouncedChangeHandler = useCallback(
debounce(changeHandler, 300)
, []);
return (
<div>
<input
onChange={debouncedChangeHandler}
type="text"
placeholder="Type a query..."
/>
{filteredNames.map(name => <div key={name}>{name}</div>)}
</div> …Run Code Online (Sandbox Code Playgroud) react-hooks ×10
reactjs ×10
usecallback ×10
javascript ×5
react-native ×2
use-effect ×2
rerender ×1
typescript ×1
use-context ×1