Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/409.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何使用钩子将功能组件转换为类组件_Javascript_Reactjs_React Hooks_Usecallback - Fatal编程技术网

Javascript 如何使用钩子将功能组件转换为类组件

Javascript 如何使用钩子将功能组件转换为类组件,javascript,reactjs,react-hooks,usecallback,Javascript,Reactjs,React Hooks,Usecallback,我试图挑战自己,将使用钩子的课程项目转换为同一个项目,但不必使用钩子来学习如何使用类组件。目前,我需要帮助了解如何在普通类组件中复制useCallback钩子。下面是它在应用程序中的使用方式 export const useMovieFetch = movieId => { const [state, setState] = useState({}); const [loading, setLoading] = useState(true); const [erro

我试图挑战自己,将使用钩子的课程项目转换为同一个项目,但不必使用钩子来学习如何使用类组件。目前,我需要帮助了解如何在普通类组件中复制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替代方案的答案。感谢您对此问题所做的任何努力。

您可以通过对给定输入使用记忆函数来复制回拨的行为,例如:movieId

你可以用


您可以通过为给定的输入使用一个记忆函数来复制secallback的行为,例如:movieId

你可以用

TL;博士

在您的特定示例中,useCallback用于生成一个引用维护的属性,作为道具传递给另一个组件。通过创建绑定方法,您不必像使用钩子那样担心依赖关系,因为所有依赖关系都作为道具或状态维护在实例上

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}/>
    }

}
大一号班轮 您会发现react中的许多钩子只是创建实例变量的机制提示:当您只有一个函数时,实例就是一个变量。

TL;博士

在您的特定示例中,useCallback用于生成一个引用维护的属性,作为道具传递给另一个组件。通过创建绑定方法,您不必像使用钩子那样担心依赖关系,因为所有依赖关系都作为道具或状态维护在实例上

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}/>
    }

}
大一号班轮
你会发现react中的很多钩子只是创建实例变量的机制。提示:当你只有一个函数时,实例就是一个变量。

我认为你最好的选择是shouldComponentUpdate:我会研究一下,看看是否能让它工作。如果我能让它工作,我会让你知道的。谢谢,仅供参考,功能组件和hooks API比类组件API更新得多,通常更受推荐,因为它们在实现关注点分离方面更好。对于类组件,您只有一个状态对象,以及每个生命周期方法中的一个,用于实现特定组件的所有逻辑。如果你只是想学习,那没关系,但是你的课程使用函数组件和钩子而不是类组件是有原因的。我认为你最好的选择是应该更新组件:我会调查一下,看看我是否能让它工作。如果我能让它工作,我会让你知道的。谢谢,仅供参考,功能组件和hooks API比类组件API更新得多,通常更受推荐,因为它们在实现关注点分离方面更好。对于类组件,您只有一个状态对象,以及每个生命周期方法中的一个,用于实现特定组件的所有逻辑。如果你只是想学习,那没关系,但是你的课程使用函数组件和钩子而不是类组件是有原因的。谢谢你提供的信息,我很快就会知道这是否有效。我仍在努力完全理解它。你能告诉我,如果我认为讲师在这里使用useCallback挂钩是正确的,因为他需要在fetchData方法中使用movieId道具,但movieId并不总是相同的。因为movieId发生了变化,所以如果movieId没有变化,useCallback将不会创建新方法,但一旦它发生变化,它将需要创建一个新的fetchData方法。对吗?@albert_anthony6 100%准确。实际上所有的钩子都是这样工作的,它们只在依赖数组中的某些内容与上次调用钩子时不同的情况下才会执行操作——最好的时候进行记忆;但是,在您的示例中,该方法作为道具传递给其他组件,但讲师对该方法所做的操作有所不同。我将把问题和其余的代码一起编辑,这样你就可以看到他是如何使用这个方法的。我不认为他把它当作道具传给任何地方,我可能错了,但你能看看自己,告诉我你认为应该做什么吗?哈,这与你的教练使用它的方式无关。它纯粹用于创建回调道具的引用完整性。没有必要像你的导师那样使用它,它实际上只会让代码变慢,因为现在它每次都要检查记忆。只需将fetchData的全部内容放在效果中即可。或者,您可以完全提取fetchData,并让它以movieId和状态设置函数作为参数。感谢您提供的信息,我将很快了解这是否有效。我仍在努力完全理解它。你能告诉我我的想法是否正确吗
讲师在这里使用了useCallback钩子,因为他需要在fetchData方法中使用movieId道具,但movieId并不总是相同的。因为movieId发生了变化,所以如果movieId没有变化,useCallback将不会创建新方法,但一旦它发生变化,它将需要创建一个新的fetchData方法。对吗?@albert_anthony6 100%准确。实际上所有的钩子都是这样工作的,它们只在依赖数组中的某些内容与上次调用钩子时不同的情况下才会执行操作——最好的时候进行记忆;但是,在您的示例中,该方法作为道具传递给其他组件,但讲师对该方法所做的操作有所不同。我将把问题和其余的代码一起编辑,这样你就可以看到他是如何使用这个方法的。我不认为他把它当作道具传给任何地方,我可能错了,但你能看看自己,告诉我你认为应该做什么吗?哈,这与你的教练使用它的方式无关。它纯粹用于创建回调道具的引用完整性。没有必要像你的导师那样使用它,它实际上只会让代码变慢,因为现在它每次都要检查记忆。只需将fetchData的全部内容放在效果中即可。或者,您可以完全提取fetchData,并让它以movieId和状态设置函数作为参数。
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 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`
   }

}