Можно ли оживить до 100% в реактивной пружине?
Я использую реагирующую пружину, чтобы попытаться анимировать содержимое AJAX по мере его загрузки.
У меня есть контейнерный компонент, который я иногда хочу анимировать до 'auto' с 0, а иногда я хочу анимировать до 100% в зависимости от пропускаемого объекта.
У меня есть const, который я установил, который затем передается в свойство selectedHeight в компоненте Transition. Затем я использую это для установки свойства высоты в свойстве стиля смонтированного дочернего компонента.
const Container = ({ data, children, stretchHeight }) => {
const loaded = data.loadStatus === 'LOADED';
const loading = data.loadStatus === 'LOADING';
const animationHeight = stretchHeight ? '100%' : 'auto';
return (
<div
className={classnames({
'data-container': true,
'is-loading': loading,
'is-loaded': loaded,
'stretch-height': stretchHeight
})}
aria-live="polite"
>
{loading &&
<div style={styles} className='data-container__spinner-wrapper'>
<LoadingSpinner />
</div>
}
<Transition
from={{ opacity: 0, calculatedHeight: 0 }}
enter={{ opacity: 1, calculatedHeight: animationHeight }}
leave={{ opacity: 0, calculatedHeight: 0 }}
config={config.slow}
>
{loaded && (styles => {
return (
<div style={{ opacity: styles.opacity, height: styles.calculatedHeight }}>
{children}
</div>
)
}
)}
</Transition>
</div>
)
}
Проблема в том, что это приводит к ошибке превышения максимального количества вызовов в стеке, так как я не думаю, что Reaction-Spring может понять строковое значение "100%", только "auto".
Есть ли обходной путь для этого?
2 ответа
Проблема в том, что вы переключаете типы, вы переходите от 0 к авто на 0%. Он может интерполировать авто, но это интерполируется как число, вы можете спутать его, смешивая это число с процентом.
PS. Может быть, вы можете немного обмануть, используя css: https://codesandbox.io/embed/xolnko178q
От & до нужной единицы (числа или строки)
const [percentage, setPercentage] = useState(100);
// wrong
const animationState2 = useSpring({
from:{width: 0},
to: {width: `${percentage}%`}
});
// right
const animationState2 = useSpring({
from:{width: '0%'},
to: {width: `${percentage}%`}
});
Спасибо @hpalu за помощь в понимании проблемы:
Проблема в том, что вы переключаете типы, вы переходите от 0 к авто на 0%. Он может интерполировать авто, но это интерполируется как число, вы можете спутать его, смешивая это число с процентом.
Чтобы решить эту проблему, я создал константы для начальной и конечной точек.
const containerHeightAnimationStart = stretchHeight ? '0%' : 0;
const containerHeightAnimationEnd = stretchHeight ? '100%' : 'auto';
Затем я использовал их в анимации:
<Transition
native
from={{ opacity: 0, height: containerHeightAnimationStart }}
enter={{ opacity: 1, height: containerHeightAnimationEnd }}
leave={{ opacity: 0, height: containerHeightAnimationStart }}
>
{loaded && (styles => {
return (
<animated.div style={styles}>
{children}
</animated.div>
)
}
)}
</Transition>