每当我在父组件中满足显示子组件的条件时,如何在子组件中执行一个函数?

时间:2019-12-15 22:01:59

标签: reactjs

我有一个名为Camera的子组件,当满足以下条件时,我会在父组件中调用它:

<Camera showCamera = {fieldPhoto} />


 
<!-- component parent -->
  handleTakePictureAsync = ({ uri, fieldphoto }) => {
    setFieldPhoto(null);

  };

    const [fieldPhoto, setFieldPhoto] = useState (null)
    return(
        <View>
         <Camera
            showCamera = {fieldPhoto}
            handleTakePictureAsync={handleTakePictureAsync}

         />
         <Button transparent onPress = {() =>
             setFieldPhoto(true)
         </Button>)
        </View>)

child组件中,我有一种方法可以验证是否已接受使用摄像头的权限,如果尚未接受,则应询问对话框,询问是否允许运行摄像头。时间直到被接受为止。

在不加载其余组件的情况下,我不知道如何显示确认消息。

<! -- Camera Component -->

  export const Camara = props => {
  const [hasPermission, setHasPermission] = useState(null);
  const [showCamera, setShowCamera] = useState(true);
  const propShowCamera = props.showCamera;

  const checkPermissionsCamera = () => {
    const status = Permissions.askAsync(Permissions.CAMERA).then(permission => {
      setHasPermission(status.status === "granted");
    });
  };

  return (
    <View>
      {checkPermissionsCamera()}
      {propShowCamera && hasPermission && ( rest of code
      .
      .
      .

我想确保在接受照相机使用权限之前不加载照相机组件的其余代码,并确保在接受照相机许可之前显示要求接受许可的消息。

enter image description here

1 个答案:

答案 0 :(得分:0)

您的父组件正在传递道具showCamera,该道具确定是否显示摄像机。由于这是布尔值,因此应将初始值设置为false而不是null

const Parent = () => {
    handleTakePictureAsync = ({ uri, fieldphoto }) => {
        setFieldPhoto(false)
    }

    const [fieldPhoto, setFieldPhoto] = useState(false)
    return (
        <View>
            <Camera
                showCamera={fieldPhoto}
                handleTakePictureAsync={handleTakePictureAsync}
            />
            <Button transparent onPress={() => setFieldPhoto(true)}></Button>
        </View>
    )
}

在子组件中,您应该使用useEffect钩子来运行checkPermissionsCamera函数-不要在render方法中直接调用它,因为此函数设置了状态,这意味着您的组件可能会重新渲染连续:

    useEffect(() => {
        const checkPermissionsCamera = () => {
            const status = Permissions.askAsync(Permissions.CAMERA).then(
                permission => {
                    setHasPermission(status.status === 'granted')
                }
            )
        }

        checkPermissionsCamera()
    }, [setHasPermission])

return (
    <View>
    // Don't do this:
    // {checkPermissionsCamera()}
    {propShowCamera && hasPermission && ( rest of code...

我也不清楚为什么需要两个showCamera值:

const [showCamera, setShowCamera] = useState(true);
const propShowCamera = props.showCamera;

也:

  

应该询问对话框,要求允许摄像机运行   次直到被接受

您确定这就是您想要的吗?一个永无休止的弹出窗口,要求获得相机许可,直到用户授予使用相机的许可?如果他们不想授予权限怎么办?您可能应该接受他们不想这样做,并显示一条消息“您需要授予相机权限才能使用应用程序的此部分”。


编写相机组件的一种方法可能是这样的:

export const Camara = ({ showCamera }) => {
    const [hasPermission, setHasPermission] = useState(false)

    useEffect(() => {
        const checkPermissionsCamera = () => {
            const status = Permissions.askAsync(Permissions.CAMERA).then(
                permission => {
                    setHasPermission(status.status === 'granted')
                }
            )
        }

        checkPermissionsCamera()
    }, [setHasPermission])

    return (
        <View>
            {showCamera && hasPermission && <div>Rest of code</div>}
        </View>
    )
}

然后,您不会在弹出窗口无限循环中欺骗用户,除非他们授予摄像头许可。

但是,如果需要显示相机的权限,为什么要首先渲染Camera组件?在父组件中处理权限请求是否更好,然后在授予权限后,渲染Camera

这也符合您的要求:

  

我想确保相机组件的其余代码是   在接受相机使用权限之前无法加载

在获得许可之前,根本不要渲染Camera


父级中的处理权限如下所示:

// Parent
const Parent = () => {
    const handleTakePictureAsync = ({ uri, fieldphoto }) => {
        setIsFieldPhoto(false)
    }

    const [hasCameraPermission, setHasCameraPermission] = useState(false)
    const [isFieldPhoto, setIsFieldPhoto] = useState(false)

    useEffect(() => {
        const requestCameraPermission = () => {
            Permissions.askAsync(Permissions.CAMERA).then(
                ({ status }) => {
                    setHasCameraPermission(status === 'granted')
                }
            )
        }

        if (!hasCameraPermission && isFieldPhoto) {
            requestCameraPermission()
        }
    }, [setHasCameraPermission, hasCameraPermission, isFieldPhoto])

    return (
        <View>
            {hasCameraPermission && isFieldPhoto && (
                <Camera handleTakePictureAsync={handleTakePictureAsync} />
            )}
            <Button transparent onPress={() => setIsFieldPhoto(true)}></Button>
        </View>
    )
}

// Camera
export const Camara = ({ handleTakePictureAsync }) => {
    return (
        <View>
            <div>Normal camera code</div>
        </View>
    )
}