我试图挑战自己,将使用钩子的课程项目转换为同一项目,而不必使用钩子来了解有关如何使用类组件做事的更多信息。当前,我需要帮助弄清楚如何在普通的类组件中复制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]){
// console.log("grabbing from localStorage");
setState(JSON.parse(localStorage[movieId]));
setLoading(false);
}else{
// console.log("Grabbing from API");
fetchData();
}
}, [fetchData, movieId])
useEffect(() => {
localStorage.setItem(movieId, JSON.stringify(state));
}, [movieId, state])
return [state, loading, error]
}
我了解如何复制其他钩子,例如useState和useEffect,但是我正在努力寻找useCallback替代方法的答案。感谢您为解决这个问题所做的任何努力。
答案 0 :(得分:3)
TL; DR
在您的特定示例中,useCallback
用于生成引用维护的属性,以作为道具传递给另一个组件。您只需创建一个bound
方法即可做到这一点(不必像使用钩子那样担心dependencies
,因为所有“依赖项”都作为props或state保留在您的实例上。 / p>
class Movie extends Component {
constructor() {
this.state = {
loading:true,
error:false,
}
}
fetchMovie() {
this.setState({error:false,loading:true});
try {
// await fetch
this.setState({
...
})
} catch(error) {
this.setState({error});
}
}
fetchMovieProp = this.fetchMovie.bind(this); <- this line is essentially "useCallback" for a class component
render() {
return <SomeOtherComponent fetchMovie={this.fetchMovieProp}/>
}
}
有关功能组件和类组件的钩子
useCallback
的美丽之处在于,要在类组件上实现它,只需声明一个实例函数,该函数是一个函数(绑定到该实例)就可以了。
useCallback
的目的是参照完整性,因此,基本上,您的React.memo
和React.PureComponent
可以正常工作。
const MyComponent = () => {
const myCallback = () => { ... do something };
return <SomeOtherComponent myCallback={myCallback}/> // every time `MyComponent` renders it will pass a new prop called `myCallback` to `SomeOtherComponent`
}
const MyComponent = () => {
const myCallback = useCallback(() => { ... do something },[...dependencies]);
return <SomeOtherComponent myCallback={myCallback}/> // every time `MyComponent` renders it will pass THE SAME callback to `SomeOtherComponent` UNLESS one of the dependencies changed
}
要在类组件中“复制” useCallback
,您无需执行任何操作:
class MyComponent extends Component {
method() { ... do something }
myCallback = this.method.bind(this); <- this is essentially `useCallback`
render() {
return <SomeOtherComponent myCallback={this.myCallback}/> // same referential integrity as `useCallback`
}
}
您会发现,许多hooks
的反应仅仅是创建有效的“实例”变量的机制(提示:“实例”是Fiber)>
答案 1 :(得分:0)
您可以通过使用给定输入(例如:useCallback
)的存储功能来复制movieId
的行为
您可以使用lodash method