#reactjs #swipe #swiperjs
#reactjs #проведите пальцем #swiper.js
Вопрос:
Я хочу, чтобы виртуальный swiper работал для react hooks. Я делаю это, чтобы обновить больше данных из api.
Я использую два пакета:
"react-id-swiper": "^3.0.0",
,
"swiper": "^5.3.6",
и "react": "^16.11.0"
.
Пример в документе api:https://swiperjs.com/api/#virtual.
Я не могу использовать виртуальный swiper с renderExternal
функцией в react hook. Хотя я пытался работать с ним.
мой код, использующий effect: 'coverflow',
:
import React, { useEffect, useState } from 'react';
import { makeStyles } from '@material-ui/styles';
import './CoverflowShow.scss';
import PropTypes from 'prop-types';
import { useHistory, useParams } from 'react-router';
import { Tooltip } from '@material-ui/core';
import Swiper from 'react-id-swiper';
const useStyles = makeStyles((theme) => ({
tooltipPlacementBottom: {
margin: theme.spacing(1, 0)
},
tooltipPlacementTop: {
margin: theme.spacing(1, 0)
},
tooltip: {
backgroundColor: theme.palette.color.main,
opacity: '0.9 !important'
},
arrow: {
color: theme.palette.color.main
}
}));
const CoverflowShow = React.memo(({
files, styleCoordinates, foods, resetState, size, removeAddnewTranslation
}) => {
const classes = useStyles();
const [coverflowSwiper, getCoverflowSwiper] = useState(null);
const history = useHistory();
const params = useParams();
const [state, setState] = useState({
// dummy slides data
slides: files,
// virtual data
virtualData: {
slides: []
}
});
/**
* @function getInitialSlide
* @description get initial slide
* @returns {Number} of initialSlide
*/
const getInitialSlide = () => {
if (files.length > 1 amp;amp; params.menu_id) {
const menuId = parseInt(params.menu_id, 0);
return files.findIndex((f) => f.id === menuId);
}
return 0;
};
/**
* @description params of Coverflow Effect
*/
const CoverflowEffect = {
getSwiper: getCoverflowSwiper,
effect: 'coverflow',
initialSlide: getInitialSlide(),
// simulateTouch: false,
centeredSlides: true,
slidesPerView: 'auto',
coverflowEffect: {
rotate: 50,
stretch: 0,
depth: 100,
modifier: 1,
slideShadows: true
},
navigation: {
nextEl: '.swiper-button-next',
prevEl: '.swiper-button-prev',
},
// virtual: {
// slides: state.slides,
// renderExternal(data) {
// setState({ ...state, virtualData: data });
// }
// },
};
useEffect(() => {
/**
* @function handleSlideChanged
* @description handle slide changed
* @param {object} is swiper
* @returns {Number|String}
*/
const handleSlideChanged = (swiper) => {
if (files.length > 1) {
const file = files[swiper.activeIndex];
resetState();
return history.push({
pathname: `/menus/${file.id}`,
search: file.current_page ? `?page=${file.current_page}` : null
});
}
return 0;
};
if (coverflowSwiper !== null) {
coverflowSwiper.virtual.slides = state.slides;
coverflowSwiper.virtual.renderExternal = (data) => setState({ ...state, virtualData: data });
coverflowSwiper.on('slideChange', () => handleSlideChanged(coverflowSwiper));
}
return () => {
if (coverflowSwiper !== null) {
coverflowSwiper.off('slideChange', () => handleSlideChanged(coverflowSwiper));
}
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [coverflowSwiper, history, state]);
/**
* @function handleOnclickFood
* @description handle onclick food and redirect food by id
*/
const handleOnclickFood = (item) => () => {
removeAddnewTranslation();
const path = `${window.location.pathname}`;
const pushStateURL = `${path}?foods=${item.id}`;
history.push(pushStateURL);
};
const coordinateOfFoods = foods.map((food) => (
<div
style={{
position: 'absolute',
height: 10,
width: 10,
borderRadius: 10,
backgroundColor: '#dd4242',
border: '1px solid #fff',
transform: 'translate(-6px, -6px)',
cursor: 'pointer'
}}
className="coordinateSlide"
onClick={handleOnclickFood(food)}
/>
));
// Render list slides has background image
const backgroundImage = state.slides.map((file) => (
// const backgroundImage = files.slides.map((file) => (
// const backgroundImage = state.virtualData.slides.map((file) => (
<div
key={file.id}
style={{
backgroundImage: `url(${file.photo})`,
backgroundSize: 'contain',
backgroundRepeat: 'no-repeat'
}}
>
{coordinateOfFoods}
<div style={styleCoordinates} className="coordinateSlide" />
</div>
));
return (
<div className="Coverflow-effect-show">
<Swiper {...CoverflowEffect}>
{backgroundImage}
</Swiper>
</div>
);
});
CoverflowShow.propTypes = {
files: PropTypes.array,
foods: PropTypes.array,
coordinates: PropTypes.object,
styleCoordinates: PropTypes.object,
size: PropTypes.object,
resetState: PropTypes.func,
removeAddnewTranslation: PropTypes.func
};
export default CoverflowShow;
Комментарии:
1. Я нашел это: reactjsexample.com/reactjs-component-for-idangerous-swiper . React-id-swiper использует виртуальный Dom, когда
import { Swiper, Virtual } from 'swiper/js/swiper.esm'
. Но это класс, а не функция. Пожалуйста, помогите мне!
Ответ №1:
Я смог решить эту проблему, повторно загрузив весь swiper
компонент вот базовый рабочий пример для react native:
это мой полный swiper, который вы увидите на картинке.
<Swiper
from={0}
minDistanceForAction={0.1}
controlsProps={{
dotsTouchable: true,
prevPos: 'left',
nextPos: 'right',
nextTitle: '>',
nextTitleStyle: {
color: 'red',
fontSize: 24,
fontWeight: '500'
},
PrevComponent: ({ onPress }) => (
<TouchableOpacity onPress={onPress}>
<Text style={{ color: 'white', fontSize: 24, fontWeight: '500' }}>
{'<'}
</Text>
</TouchableOpacity>
),
}}
>
Комментарии:
1. Пожалуйста, не включайте код в виде изображения, а вставьте код непосредственно в свой ответ.