如何使用钩子将功能组件转换为 class 组件
How to convert functional component using hooks to class component
我正在尝试挑战自己,将使用挂钩的课程项目转换为同一个项目,但不必使用挂钩,以便了解有关如何使用 class 组件进行操作的更多信息。目前,我需要帮助弄清楚如何在普通 class 组件中复制 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
的答案。感谢您为这个问题付出的努力。
您可以通过对给定输入使用记忆函数来复制useCallback
的行为(例如:movieId
)
您可以使用lodash method
TL;DR
在您的特定示例中,useCallback
用于生成引用维护的 属性 以作为道具传递给另一个组件。您只需创建一个 bound
方法即可做到这一点(您不必像使用钩子那样担心 dependencies
,因为所有依赖项都作为道具或状态在您的实例上维护。
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}/>
}
}
更多关于函数式 vs class 组件的钩子
useCallback
的美妙之处在于,要在 class 组件上实现它,只需声明一个实例 属性,它是一个函数(绑定到实例),然后您重新完成。
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
}
要在 class 组件中复制 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`
}
}
大班轮
你会发现 React 中的 hooks
只是一种创建实例变量的机制(提示:“实例”是一个 Fiber),而你只有一个函数。
我正在尝试挑战自己,将使用挂钩的课程项目转换为同一个项目,但不必使用挂钩,以便了解有关如何使用 class 组件进行操作的更多信息。目前,我需要帮助弄清楚如何在普通 class 组件中复制 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
的答案。感谢您为这个问题付出的努力。
您可以通过对给定输入使用记忆函数来复制useCallback
的行为(例如:movieId
)
您可以使用lodash method
TL;DR
在您的特定示例中,useCallback
用于生成引用维护的 属性 以作为道具传递给另一个组件。您只需创建一个 bound
方法即可做到这一点(您不必像使用钩子那样担心 dependencies
,因为所有依赖项都作为道具或状态在您的实例上维护。
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}/>
}
}
更多关于函数式 vs class 组件的钩子
useCallback
的美妙之处在于,要在 class 组件上实现它,只需声明一个实例 属性,它是一个函数(绑定到实例),然后您重新完成。
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
}
要在 class 组件中复制 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`
}
}
大班轮
你会发现 React 中的 hooks
只是一种创建实例变量的机制(提示:“实例”是一个 Fiber),而你只有一个函数。