#react-native #onload #zooming
#react-native #загрузка #масштабирование
Вопрос:
При выполнении следующего кода без компонента useEffect
ImageZoom консоль подключения регистрирует следующее: Object { "height": 412, "width": 231.66666666666666, }
какая правильная высота и ширина изображения при загрузке (размер отображаемого изображения).
но когда я добавляю ImageZoom
компонент, я получаю исключение компонента, которое не может прочитать свойство « width
of undefined
.
const ImageModal = ({ image, isOpenImage, onStateChange }) => {
const [imageLoad, setImageLoad] = useState({ width: null, height: null });
const handleLoad = (event) => {
setImageLoad({
width: event.nativeEvent.source.width,
height: event.nativeEvent.source.height,
});
};
useEffect(() => {
console.log(imageLoad);
}, [imageLoad]);
const NewImage = useCallback(
() => (
<Image
onLoad={(event) => handleLoad(event)}
source={image}
style={{ flex: 1 }}
resizeMode="contain"
/>
),
[]
);
return (
<Modal
style={{ flex: 1 }}
animationType="slide"
transparent={true}
visible={isOpenImage}>
<Fragment>
<View
style={{
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
backgroundColor: '#000000',
opacity: 0.5,
}}
/>
<View
style={{
position: 'absolute',
bottom: 22.5,
zIndex: 2,
alignSelf: 'center',
}}>
<TouchableOpacity
onPress={() => {
onStateChange(false);
}}
style={{
width: 130,
height: 47,
borderRadius: 50,
borderWidth: 2,
borderColor: '#fff',
backgroundColor: '#2e423d',
transform: [{ scaleX: 1 }],
justifyContent: 'center',
}}>
<Text
style={{
fontSize: 18.8,
fontFamily: 'OpenSansHebrew-Regular',
color: '#ffffff',
alignSelf: 'center',
}}>
סגירה
</Text>
</TouchableOpacity>
</View>
<View
style={{
flex: 1,
backgroundColor: 'white',
marginBottom: 0,
marginHorizontal: 15,
borderRadius: 20,
}}>
<View
style={{
flex: 1,
backgroundColor: 'white',
marginBottom: 0,
marginBottom: 250,
marginTop: 150,
justifyContent: 'center',
}}>
<ImageZoom
cropWidth={screenWidth}
cropHeight={screenHeight}
imageWidth={imageLoad.width}
imageHeight={imageLoad.height}>
<NewImage />
</ImageZoom>
</View>
</View>
</Fragment>
</Modal>
);
};
Ответ №1:
попробуйте инициализировать imageLoad
состояние некоторыми данными.
const [imageLoad, setImageLoad] = useState({width: 0, height: 0});
Комментарии:
1. в первый раз, когда компонент отображает, он имеет значение undefined, поскольку вы не инициализировали его в перехватах useState, поэтому вы получите эту ошибку, поэтому, чтобы избежать этого, вы должны указать это значение. и еще одна вещь, подумайте о преобразовании ширины и высоты в int,
Math.floor()
иногда это вызывает странное поведение на iPhone.2. Обратите внимание, что компонентом, о котором я говорю, является ImageZoom, теперь я инициализировал значения null, и ImageZoom получает imageLoad.width=null и imageLoad.height = null, поэтому он все еще не работает, и я ничего не вижу на своем iphone. надеюсь, вы сможете помочь мне решить эту проблему, спасибо вам в любом случае!
3. и нет журнала консоли, как и раньше
Ответ №2:
Вы инициализируете состояние imageLoad с пустым значением. Прежде всего, вы должны определить ширину и высоту значения в вашем крючке useState следующим образом —
const [imageLoad, setImageLoad] = useState({width:null, height: null});
Отображается ошибка, потому что вы не определили свои объекты width и height в состоянии imageLoad.
согласно вашему комментарию, кажется, что ваше состояние не обновляется до рендеринга компонента ImageZoom.
Сначала попробуйте обновить состояние перед визуализацией ImageZoom, для этого вы можете создать новое состояние с именем imageLoaded, а затем обновить это состояние в вашем useEffect следующим образом ->
const [imageLoaded , setImageLoaded ] = useState(false);
useEffect(() => {
getDimensions ()
}, []);
const getDimensions = (url) => {
var img = new Image();
img.src = url;
img.onload = ()=> { setImageLoad({
width: img.width,
height: img.height,
})
setImageLoaded(true) }
}
Теперь визуализируйте компонент в состоянии загрузки изображения
ImageLoaded ?
<ImageZoom
cropWidth={screenWidth}
cropHeight={screenHeight}
imageWidth={imageLoad.width}
imageHeight={imageLoad.height}>
<NewImage />
</ImageZoom>
: null;
Теперь вам не нужно событие onLoad в вашем компоненте изображения
Комментарии:
1. Обратите внимание, что компонентом, о котором я говорю, является ImageZoom, теперь я определил значения, и ImageZoom получает imageLoad.width=null и imageLoad.height = null, поэтому он все еще не работает. надеюсь, вы сможете помочь мне решить эту проблему, спасибо вам в любом случае!
2. Причина в том, что ваш компонент imageZoom отображается перед загрузкой изображения, поэтому он принимает начальные значения, чтобы предотвратить это обновление состояний перед визуализацией ImageZoom. Для этого вы можете использовать объект img из javascript.
3. по-прежнему не работает, у меня ошибка изображение не является конструктором, и я думаю, что это все равно не сработает, потому что я ищу размер отображаемого изображения, а не его реальный размер.
4. в вашем коде он уже извлекает фактический размер в методе onLoad , поэтому вам придется повторно отобразить родительский компонент <ImageZoom/> и убедиться, что в следующий раз событие onLoad не выполняется.