使用状态更新后防止渲染相机
Prevent Render of Camera After useState update
我有一个设置了叠加模板的相机。一切正常,问题是每次您更改滑块以管理模板的不透明度时,都会导致屏幕完全重新渲染。这会使相机屏幕变黑一两秒钟,然后一切 returns 恢复正常。如果您将滑块移动太多,将导致应用程序完全崩溃。
有谁知道如何在不一直重新渲染的情况下获得所需的效果?这是代码:
import React, { useRef, useState, useEffect, useContext } from "react";
import { Camera } from "expo-camera";
import styled from "styled-components";
import { View, TouchableOpacity, ImageBackground, Image, Dimensions } from 'react-native';
import { Button } from "react-native-paper";
import Slider from '@react-native-community/slider';
import { Text } from "../../components/typography/text.component";
const CameraBackground = styled(View)`
background-color: #222;
`;
const ImageContainer = styled(View)`
flex: 1;
background-color: #000;
`;
const SnapButtonContainer = styled(TouchableOpacity)`
position: absolute;
z-index: 10000;
top: 50%;
margin-top: -40px;
right: 10px;
`;
const SnapButton = styled(Button)`
border: 1px #b22222 solid;
width: 60px;
height: 60px;
background-color: #8b0000;
border-radius: 50px;
`;
const OpacitySlider = styled(Slider)`
z-index: 1000;
width: 400px;
position: absolute;
top: 10px;
left: 50%;
margin-left: -200px;
`;
export const CameraScreen = ({ route, navigation }) => {
const cameraRef = useRef();
const [hasPermission, setHasPermission] = useState(null);
const [photo, setPhoto] = useState(null);
const [opacity, setOpacity] = useState(0.5);
const PlaceHolderImageContainer = styled(Image)`
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0;
bottom: 0;
right: 0;
z-index: 999;
opacity: ${opacity};
flex: 1;
`;
const CameraContainer = styled(Camera)`
height: 100%;
margin: 0 auto;
width: 100%
`;
const snap = async () => {
if (cameraRef) {
let photoTaken = await cameraRef.current.takePictureAsync();
setPhoto(photoTaken);
}
};
useEffect(() => {
(async () => {
const { status } = await Camera.requestPermissionsAsync();
setHasPermission(status === 'granted');
})();
}, []);
if (hasPermission === null) {
return <View />;
}
if (hasPermission === false) {
return <Text>This app does not have access to your camera</Text>
}
return (
<CameraBackground>
<SnapButtonContainer onPress={snap}>
<SnapButton />
</SnapButtonContainer>
<OpacitySlider
minimumValue={0}
maximumValue={1}
step={0.1}
minimumTrackTintColor="#FFFFFF"
maximumTrackTintColor="#000000"
value={opacity}
onValueChange={(v) => {setOpacity(v)}}
/>
<PlaceHolderImageContainer />
<CameraContainer
ref={(camera) => (cameraRef.current = camera)}
type={Camera.Constants.Type.back}
/>
</CameraBackground>
);
};
问题是您正在更新主要组件中的状态,这会触发所有其他组件(如相机)的重新渲染,您应该做的是将图像和滑块提取到它们自己的组件中,例如:
const ImageSlider = () => {
const [opacity, setOpacity] = useState(0.5);
const PlaceHolderImageContainer = styled(Image)`
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0;
bottom: 0;
right: 0;
z-index: 999;
opacity: ${opacity};
flex: 1;
`;
return (
<>
<OpacitySlider
minimumValue={0}
maximumValue={1}
step={0.1}
minimumTrackTintColor="#FFFFFF"
maximumTrackTintColor="#000000"
value={opacity}
onValueChange={(v) => {
console.log(v);
setOpacity(v);
}}
/>
<PlaceHolderImageContainer
//source={} //add source here
/>
</>
);
};
然后在您自己的组件中使用它,例如:
<CameraBackground>
//...
<ImageSlider />
//...
</CameraBackground>
我有一个设置了叠加模板的相机。一切正常,问题是每次您更改滑块以管理模板的不透明度时,都会导致屏幕完全重新渲染。这会使相机屏幕变黑一两秒钟,然后一切 returns 恢复正常。如果您将滑块移动太多,将导致应用程序完全崩溃。
有谁知道如何在不一直重新渲染的情况下获得所需的效果?这是代码:
import React, { useRef, useState, useEffect, useContext } from "react";
import { Camera } from "expo-camera";
import styled from "styled-components";
import { View, TouchableOpacity, ImageBackground, Image, Dimensions } from 'react-native';
import { Button } from "react-native-paper";
import Slider from '@react-native-community/slider';
import { Text } from "../../components/typography/text.component";
const CameraBackground = styled(View)`
background-color: #222;
`;
const ImageContainer = styled(View)`
flex: 1;
background-color: #000;
`;
const SnapButtonContainer = styled(TouchableOpacity)`
position: absolute;
z-index: 10000;
top: 50%;
margin-top: -40px;
right: 10px;
`;
const SnapButton = styled(Button)`
border: 1px #b22222 solid;
width: 60px;
height: 60px;
background-color: #8b0000;
border-radius: 50px;
`;
const OpacitySlider = styled(Slider)`
z-index: 1000;
width: 400px;
position: absolute;
top: 10px;
left: 50%;
margin-left: -200px;
`;
export const CameraScreen = ({ route, navigation }) => {
const cameraRef = useRef();
const [hasPermission, setHasPermission] = useState(null);
const [photo, setPhoto] = useState(null);
const [opacity, setOpacity] = useState(0.5);
const PlaceHolderImageContainer = styled(Image)`
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0;
bottom: 0;
right: 0;
z-index: 999;
opacity: ${opacity};
flex: 1;
`;
const CameraContainer = styled(Camera)`
height: 100%;
margin: 0 auto;
width: 100%
`;
const snap = async () => {
if (cameraRef) {
let photoTaken = await cameraRef.current.takePictureAsync();
setPhoto(photoTaken);
}
};
useEffect(() => {
(async () => {
const { status } = await Camera.requestPermissionsAsync();
setHasPermission(status === 'granted');
})();
}, []);
if (hasPermission === null) {
return <View />;
}
if (hasPermission === false) {
return <Text>This app does not have access to your camera</Text>
}
return (
<CameraBackground>
<SnapButtonContainer onPress={snap}>
<SnapButton />
</SnapButtonContainer>
<OpacitySlider
minimumValue={0}
maximumValue={1}
step={0.1}
minimumTrackTintColor="#FFFFFF"
maximumTrackTintColor="#000000"
value={opacity}
onValueChange={(v) => {setOpacity(v)}}
/>
<PlaceHolderImageContainer />
<CameraContainer
ref={(camera) => (cameraRef.current = camera)}
type={Camera.Constants.Type.back}
/>
</CameraBackground>
);
};
问题是您正在更新主要组件中的状态,这会触发所有其他组件(如相机)的重新渲染,您应该做的是将图像和滑块提取到它们自己的组件中,例如:
const ImageSlider = () => {
const [opacity, setOpacity] = useState(0.5);
const PlaceHolderImageContainer = styled(Image)`
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0;
bottom: 0;
right: 0;
z-index: 999;
opacity: ${opacity};
flex: 1;
`;
return (
<>
<OpacitySlider
minimumValue={0}
maximumValue={1}
step={0.1}
minimumTrackTintColor="#FFFFFF"
maximumTrackTintColor="#000000"
value={opacity}
onValueChange={(v) => {
console.log(v);
setOpacity(v);
}}
/>
<PlaceHolderImageContainer
//source={} //add source here
/>
</>
);
};
然后在您自己的组件中使用它,例如:
<CameraBackground>
//...
<ImageSlider />
//...
</CameraBackground>