使用钩子(setState,useEffect)从屏幕中提取重复代码的最佳方法?

Best approach to extract repeated code from screens using hooks (setState, useEffect)?

这个问题可能看起来有点含糊,我刚开始使用钩子,我会在我的示例中非常具体,我有 3 个变量,它们具有 setter,以及一个适用于它们的 useEffect .该代码基本上要求用户提供位置权限并保存他的位置。

这段代码在两个不同的screen中复用一模一样,我的问题是,将所有代码变量和setters移动到第三个文件中使用effect在多大程度上是可行的"helper".

这是一段代码:

  const [localitzacioActual, setlocalitzacioActual] = useState(null);
  const [localitzacioPermisos, setlocalitzacioPermisos] = useState(null);
  const [mapRegion, setMapRegion] = useState(null);

  useEffect( () => {
    const demanarPermisos = async () => {
      let { status } = await Permissions.askAsync(Permissions.LOCATION);
      if (status !== 'granted') {
        setlocalitzacioPermisos('Permisos denegats')
      } else {
        setlocalitzacioPermisos(true)
      }
      let location = await Location.getCurrentPositionAsync({});
      setlocalitzacioActual(JSON.stringify(location))
      setMapRegion({ latitude: location.coords.latitude, longitude: location.coords.longitude, latitudeDelta: 0.0022, longitudeDelta: 0.0121 });
    }
    demanarPermisos()
  }, []);

到什么时候我可以将这段代码实例化到另一个文件,y仍然需要声明常量和使用效果但我可以将所有登录移动到文件外的第三个函数?

谢谢!

好吧,我会回答我自己的问题。对于任何想知道同样事情的人:

是的,可以将所有代码移出到第三个函数。只需在屏幕中添加一个 return 以及您需要的所有变量:

LocalitzacioHelper.js

import React, {useState, useEffect} from 'react';
import * as Location from 'expo-location';
import * as Permissions from 'expo-permissions';

export const demanarLocalitzacio = () => {
  const [localitzacioActual, setlocalitzacioActual] = useState(null);
  const [localitzacioPermisos, setlocalitzacioPermisos] = useState(null);
  const [mapRegion, setMapRegion] = useState(null);

  useEffect( () => {
    const demanarPermisos = async () => {
      let { status } = await Permissions.askAsync(Permissions.LOCATION);
      if (status !== 'granted') {
        setlocalitzacioPermisos('Permisos denegats')
      } else {
        setlocalitzacioPermisos(true)
      }
      let location = await Location.getCurrentPositionAsync({});
      setlocalitzacioActual(JSON.stringify(location))
      setMapRegion({ latitude: location.coords.latitude, longitude: location.coords.longitude, latitudeDelta: 0.0022, longitudeDelta: 0.0121 });
    }
    demanarPermisos()
  }, []);

  return [localitzacioActual, localitzacioPermisos, mapRegion]
}

然后在屏幕中您只需调用 return:

之前的函数

MapaScreen.js

const [localitzacioActual, localitzacioPermisos, mapRegion] = demanarLocalitzacio()

使用效果将具有与直接在屏幕渲染函数中完全相同的行为。

您可以将所有状态变量和函数放在自定义挂钩中。您的自定义挂钩将为您处理状态更改。

permisos.js

import { useState } from 'react';

const usePermisos= () => {
  const [localitzacioActual, setlocalitzacioActual] = useState(null);
  const [localitzacioPermisos, setlocalitzacioPermisos] = useState(null);
  const [mapRegion, setMapRegion] = useState(null);

  const demanarPermisos = async () => {
    let { status } = await Permissions.askAsync(Permissions.LOCATION);
    if (status !== 'granted') {
      setlocalitzacioPermisos('Permisos denegats')
    } else {
      setlocalitzacioPermisos(true)
    }
    let location = await Location.getCurrentPositionAsync({});
    setlocalitzacioActual(JSON.stringify(location))
    setMapRegion({ latitude: location.coords.latitude, longitude: location.coords.longitude, latitudeDelta: 0.0022, longitudeDelta: 0.0121 });
  };

  return [
    localitzacioActual,
    localitzacioPermisos,
    mapRegion,
    demanarPermisos,
  ];
};

export default usePermisos;

然后在需要的地方导入它们。您仍然必须使用 useEffect 来触发您的功能。

screen1.js

import React, { useEffect } from 'react';
import usePermisos from './usePermisos';

const screen1 = () => {
  const [
    localitzacioActual,
    localitzacioPermisos,
    mapRegion,
    demanarPermisos,
  ] = usePermisos();

  useEffect(demanarPermisos, []);

  return (
    <div>React Functional Component</div>
  );
};

export default screen1;

如果您需要 demanarPermisos 之外的 setter,您可以 return 从 usePermisos