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

时间:2019-07-02 18:43:34

标签: javascript reactjs react-native react-hooks

这个问题似乎有点模糊,我是使用钩子的新手,在我的示例中将非常具体,我有3个变量,包括它们的setter和对它们起作用的useEffect。该代码基本上会询问用户位置许可并保存其职位。

这段代码在两个不同的屏幕中完全相同地重用,我的问题是,将所有代码变量和设置器移动到第三个文件“ 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()
  }, []);

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

谢谢!

2 个答案:

答案 0 :(得分:1)

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

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之外的二传手,则可以从usePermisos退回。

答案 1 :(得分:0)

好吧,我会回答我自己的问题。对于想知道同一件事的人:

是的,可以将所有代码移至第三个功能。只需在屏幕上添加包含所有所需变量的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]
}

然后在屏幕中,您只需在返回之前调用该函数:

  

MapaScreen.js

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

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