我在浏览器的 localhost 端口上收到一条错误消息,我还没有部署我的代码:
类型错误:Object(...) 不是函数
NewEvent src/events/pages/NewEvent.js:51
这是我在 package.json 中的反应版本:
"dependencies": {
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-router-dom": "5.2.0",
"react-scripts": "^3.2.0",
"react-transition-group": "^4.4.1"
},
Run Code Online (Sandbox Code Playgroud)
我在我的页面中导入了 NewEvent.js :
import React, {useCallBack , useReducer} from 'react';
Run Code Online (Sandbox Code Playgroud)
在同一页面中,我将另一个函数嵌套在一个函数中:
const [formState, dispatch] = useReducer(formReducer, {
inputs: {
title: {
value: '',
isValid: false
},
description: {
value: '',
isValid: false
}
},
isValid: false
});// this is the initial state that needs to be update in the reducer
const inputHandler = useCallBack((id,value,isValid) => {
dispatch({ …Run Code Online (Sandbox Code Playgroud) 当传递回调函数时,尤其是传递参数化函数时,我知道应该使用钩子,useCallback因为使用匿名函数会对性能产生不利影响。
我说的匿名函数的例子就是这样的。
import React, { useState } from 'react';
const Component = () => {
const [param, setParam] = useState('');
...
return (
...
<SomeComponent
onClick={() => setParam('parameter')}
{...others}
/>
);
}
Run Code Online (Sandbox Code Playgroud)
在转换匿名函数以使用此钩子的过程中,我遇到了一个错误,提示“渲染次数过多”或者它无法正常工作。但具体是在什么情况下、什么情况下我也不清楚。
我用useCallback如下。
import React, { useState, useCallback } from 'react';
const Component = () => {
const [param, setParam] = useState('');
const handleClick = useCallback((params) => {
setParam(params);
},[]);
...
return (
...
<SomeComponent
onClick={handleClick('parameter')}
{...others}
/>
);
}
Run Code Online (Sandbox Code Playgroud)
但是,当使用匿名函数在 内返回时useCallback …
javascript anonymous-function reactjs react-hooks usecallback
我正在尝试挑战自己,将使用钩子的课程项目转换为同一个项目,但不必使用钩子,以便了解有关如何使用类组件做事的更多信息。目前,我需要帮助弄清楚如何在普通类组件中复制 useCallback 钩子。以下是它在应用程序中的使用方式。
export const useMovieFetch = movieId => {
const [state, setState] = useState({});
const [loading, setLoading] = useState(true);
const [error, setError] = useState(false);
const fetchData = useCallback(async () => {
setError(false);
setLoading(true);
try{
const endpoint = `${API_URL}movie/${movieId}?api_key=${API_KEY}`;
const result = await(await fetch(endpoint)).json();
const creditsEndpoint = `${API_URL}movie/${movieId}/credits?api_key=${API_KEY}`;
const creditsResult = await (await fetch(creditsEndpoint)).json();
const directors = creditsResult.crew.filter(member => member.job === 'Director');
setState({
...result,
actors: creditsResult.cast,
directors
});
}catch(error){
setError(true);
console.log(error);
}
setLoading(false);
}, [movieId])
useEffect(() => {
if(localStorage[movieId]){
// …Run Code Online (Sandbox Code Playgroud) 请跟随我的代码段下面,当我点击任何按钮(添加,编辑,删除)我所有的部件得到重新渲染,包括Title它没有成分props或stats。如果我有几个组件可能没问题,但假设我有超过15 个或更多的组件来获取/保存数据,这是可以的还是应该避免?
我尝试使用useCallback钩子(使用handleRemove),但显然这不能按预期工作。
const Button = ({ title, count, onClick }) => {
console.log(`Rendering ${title}`)
return (
<button onClick={onClick}>
{title} ({count})
</button>
)
}
const Header = () => {
console.log("Rendering Title")
return <h1>App Title</h1>
}
const Parent = () => {
const [add, setAdd] = React.useState(0)
const [edit, setEdit] = React.useState(0)
const [remove, setRemove] = React.useState(0)
const handleAdd = () => setAdd(add + 1)
const …Run Code Online (Sandbox Code Playgroud)我有几个组件都在onPress处理程序上调用相同的函数,假设它如下所示:
function MyComponent () {
const dispatch = useDispatch()
const updateThing = React.useCallback((thingId: string) => {
dispatch(someActionCreator(thingId))
someGlobalFunction(thingId)
}, [dispatch])
return (
<View>
<NestedComponent onUpdate={updateThing} />
</View>
)
}
Run Code Online (Sandbox Code Playgroud)
我想把这个函数移到组件之外,这样我就可以重新使用它,认为它看起来像这样:
const updateThing = React.useCallback(myFunction)
Run Code Online (Sandbox Code Playgroud)
但是,它有一个dispatch我需要传入并添加到依赖项数组的依赖项。
我怎样才能将这个函数分解出来以供重用,同时还能从中获得性能增益useCallback?
在我的 React 应用程序中,我渲染了不同的<Item>组件实例,我希望它们在上下文中注册/取消注册,具体取决于它们当前是否已安装。
我正在使用两个上下文(ItemContext提供已注册的项目,ItemContextSetters提供注册/取消注册的功能)来执行此操作。
const ItemContext = React.createContext({});
const ItemContextSetters = React.createContext({
registerItem: (id, data) => undefined,
unregisterItem: (id) => undefined
});
function ContextController(props) {
const [items, setItems] = useState({});
const unregisterItem = useCallback(
(id) => {
const itemsUpdate = { ...items };
delete itemsUpdate[id];
setItems(itemsUpdate);
},
[items]
);
const registerItem = useCallback(
(id, data) => {
if (items.hasOwnProperty(id) && items[id] === data) {
return;
}
const itemsUpdate = { ...items, [id]: data }; …Run Code Online (Sandbox Code Playgroud) 我有这个自定义钩子:
const useSomething = () => {
const displayAlert = (text) => {
alert(text);
};
return {displayAlert};
};
Run Code Online (Sandbox Code Playgroud)
现在我想在我的代码中的某个地方使用它,如下所示:
const SampleComponent = () => {
const {displayAlert} = useSomething();
const navigateHandler = (event, page) => {
// some api
// ...
displayAlert('Some alert');
};
const navigateHandlerCallback = useCallback(() => {
navigateHandler(null, 1);
}, []);
useEffect(navigateHandlerCallback, []);
return (
<button onClick={e => { navigateHandler(e, 5); }}>
Navigate to 5th page
</button>
)
};
Run Code Online (Sandbox Code Playgroud)
现在的问题是 eslint 警告:
React Hook useCallback 缺少依赖项:“navigateHandler”。包含它或删除依赖项数组
当我将其 …
在外面柜台在很多的YouTube视频教程看到的例子,什么是实用/现实世界中使用案例useMemo和useCallback?
另外,我只看到了钩子的输入焦点示例useRef。
请分享您为这些钩子找到的其他用例。
据我了解,您使用 useCallback 来防止重新渲染,因此我一直在每个函数中使用它,而我的蜘蛛感觉告诉我这听起来已经很糟糕了。
但故事并没有就此结束,因为我一直在到处使用它,所以我现在将依赖项传递给我的所有子组件,他们不需要担心,如下例所示:
编辑//沙盒: https://codesandbox.io/s/bold-noether-0wdnp?file =/src/App.js
父组件(需要 colorButtons 和 currentColor)
const ColorPicker = ({onChange}) => {
const [currentColor, setCurrentColor] = useState({r: 255, g:0, b: 0})
const [colorButtons, setColorButtons] = useState({0: null})
const handleColorButtons = useCallback((isToggled, id) => {
/* code that uses colorButtons and currentColor */
}, [colorButtons, currentColor])
return <div className="color-picker">
<RgbColorPicker color={currentColor} onChange={setCurrentColor} />
<div className="color-buttons">
{
Object.entries(colorButtons).map(button => <ColorButton
//...
currentColor={currentColor}
onClick={handleColorButtons}
colorButtons={colorButtons}
/>)
}
</div>
</div>
}
Run Code Online (Sandbox Code Playgroud)
第一个子级(需要 style 和 currentColor,但从其父级免费获取 colorButtons)
const ColorButton = …Run Code Online (Sandbox Code Playgroud) 在我读过的反应文档中
传递内联回调和依赖项数组。useCallback 将返回回调的记忆版本,仅当依赖项之一发生更改时该版本才会更改。当将回调传递给依赖引用相等性来防止不必要的渲染的优化子组件时(例如,shouldComponentUpdate),这非常有用。
没关系,我们需要防止子组件不必要的渲染,但是对于当前使用 的组件useCallback,真正提供了什么useCallback?
据我所知useCallback,是为了防止当前组件重新渲染一遍又一遍地创建相同的函数(如果我错了,请纠正我),并且它将保留对相同函数的引用(不创建新函数):只要依赖项数组包含相同的引用即可。
这样对吗?或者我们有更深层次的东西?
我已经检查了这个很好的答案,但它谈论的是防止(子级)重新渲染,我正在寻找useCallback当前组件的含义。
我在 React 官方文档或 blagosphere 上还没有找到任何提及这一点的信息。
我认为当你有多个状态变量时你可以而且通常应该做这样的事情:
function MyComponent() {
const [foo, setFoo] = useState(0);
const [bar, setBar] = useState(1);
return (
<div>
<div onClick={() => setFoo(foo+1)}>{foo}</div>
<div onClick={() => setBar(bar+1)}>{bar}</div>
</div>
);
}
Run Code Online (Sandbox Code Playgroud)
是否允许并鼓励这样做,而不是使用useState一个包含state字段foo和的包罗万象的对象来调用一次bar?如果允许并鼓励这样做,那么useState每次调用时如何知道它是指已存储的foo还是已存储的bar?
我也有基本相同的问题useCallback。我想知道,如果我useCallback在同一个组件中调用两次以创建两个不同的回调,如何知道useCallback我要引用之前定义的函数与创建新函数,并且如果引用已使用的函数,则需要返回记忆的函数的版本,它如何知道两者中的哪一个?特别是如果两个回调具有相同的依赖项列表?
reactjs ×11
usecallback ×11
react-hooks ×10
javascript ×6
dependencies ×1
object ×1
react-dom ×1
react-native ×1
use-effect ×1
use-ref ×1
use-state ×1