首页 > 解决方案 > 每次在父组件中满足条件以显示子组件时,如何在子组件中执行函数?

问题描述

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
      .
      .
      .

我想确保在接受相机使用权限之前不会加载相机组件的其余代码,并且在接受权限之前出现要求接受权限的消息。

在此处输入图像描述

标签: reactjs

解决方案


您的父组件正在传递showCamera决定是否显示相机的道具。由于这是一个布尔值,您应该将初始值设置为falseand not 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>
    )
}

推荐阅读