反应如何使功能与状态?

问题描述

我正在学习 React Native 并且无法理解如何制作函数或组件而不是我的代码的重复部分:

export const PostScreen = () => {

    const postId = 1

    /* THIS PART IS REPEATED IN MANY FILES */
    const [data,setData] = useState([]);
    const [loader,setLoader] = useState(false);
    const [error,setError] = useState(null);
    
    const fetchData = async () => {
        setError(null)
        setLoader(true)
        try {
            const data = await Api.get(`http://localhost/api/posts/${postId}`)
            if (data.success == 1) {
                setData(data.data)
            }
            else {
                setError(data.error)
            }
            
        }
        catch(e) {
            console.log(e)
            setError('Some problems')
        }
        finally {
            setLoader(false)
        }
       
    }

    useEffect(() => {
        fetchData()
    },[])

    if (loader) {
        return <Loader />
    }

    if (error) {
        return <View><Text>{error}</Text></View>
    }

    /*END>>> THIS PART IS REPEATED IN MANY FILES */

    return (
        <View><Text>{data.title}</Text></View>
    )
}

问题是 fetchData 正在处理状态。我发现,如何用 Context 做到这一点,但我不会使用它。有没有办法在没有上下文的情况下做清晰的代码

解决方法

那么,为什么不自己制作 hook 呢?

在专用模块中编写钩子:

function useMyOwnHook(props) {
    const {
        postId,} = props;

    const [data,setData] = useState([]);
    const [loader,setLoader] = useState(false);
    const [error,setError] = useState(null);
    
    const fetchData = async () => {
        setError(null)
        setLoader(true)
        try {
            const data = await Api.get(`http://localhost/api/posts/${postId}`)
            if (data.success == 1) {
                setData(data.data)
            }
            else {
                setError(data.error)
            }
            
        }
        catch(e) {
            console.log(e)
            setError('Some problems')
        }
        finally {
            setLoader(false)
        }
       
    }

    useEffect(() => {
        fetchData()
    },[])

    const render = loader
        ? <Loader />
        : error
            ? <View><Text>{error}</Text></View>
            : null;

    return {
        data,render,}
}

此时,组件将被编写如下:

export const PostScreen = () => {

    const postId = 1

    const {
        render,data,} = useMyOwnHook({ postId });

    return render ?? (
        <View><Text>{data.title}</Text></View>
    )
}