Пытаюсь сделать анимацию перехода на другую страницу следующим образом: Для начала я обернул в HashRouter мой контейнер, который меняется при смене адреса.Далее я создал компонент второй страницы, для которой прописал два класса со стилями, первый основной. в которой все дефолтные свойства + скрытие за пределы body, т.е. transform: translateX(100%); и transition 0.4s;, а второму классу, который добавляется при изменении состояния компонента дал transform: translateX(0);. В итоге анимация не работает, хотя я использую componentDidMoutn(), т.е. после того как компонент уже отрендерился я меняю его состояние. Новая страница появляется моментально, а не плавно выплывает.
Код самой страницы, которая должна появится:
import React from 'react';
import './SearchPage.css';
class SearchPage extends React.Component {
constructor() {
super();
this.state= {
onDisplay: false,
}
}
componentDidMount() {
this.setState({
onDisplay: true,
})
}
render() {
let classList = '';
if(this.state.onDisplay == false) {
classList = 'SearchPage';
} else {
classList = 'SearchPage SearchPage--active';
}
return(
<div className={classList}></div>
)
}
}
export default SearchPage;
.SearchPage {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.3);
transform: translateX(100%);
transition: .4s;
}
.SearchPage--active {
transform: translateX(0);
}
Код страницы на которой происходит навигация:
import React from 'react';
import MainPage from '../MainPage';
import LeftNav from '../LeftNav';
import SearchPage from '../SearchPage';
import Menu from '../Menu';
import './App.css';
import {HashRouter, Route, Link} from 'react-router-dom';
class App extends React.Component {
constructor() {
super();
this.state = {
open: false,
}
this.onOpen = () => {
this.setState({
open: !this.state.open,
})
}
}
render() {
let classList = '';
if(this.state.open == true) {
classList = 'main-wrapper main-wrapper--active';
} else {
classList = 'main-wrapper'
}
return(
<div>
<Menu onOpen={this.onOpen} />
<HashRouter>
<main className={classList}>
<Route exact path='/' component={MainPage} />
<Route exact path='/search' component={SearchPage} />
</main>
</HashRouter>
</div>
)
}
}
export default App;
Дело в том что CSS анимация при добавлении класса .SearchPage--active не отрабатывает, потому что нет ререндера и значение transform не меняется, а ставится сразу в translateX(0);. Чтобы инициировать изменение этого значения можно использовать setTimeout. В этом случае страница отрендерится с начальным значением transform: translateX(100%);, а потом по таймауту перерендерит с новым класом и значением. Но смелюсь предложить второй вариант, без ререндера и JS в целом, который является очевидно производительнее.
Вариант №1: setTimeout
class SearchPage extends React.Component {
constructor() {
super();
this.state= {
onDisplay: false,
}
}
componentDidMount() {
setTimeout(() => {
this.setState({
onDisplay: true,
})
}, 0)
}
render() {
let classList = '';
if(this.state.onDisplay === false) {
classList = 'SearchPage';
} else {
classList = 'SearchPage SearchPage--active';
}
return(
<div className={classList}>lala</div>
)
}
}
ReactDOM.render(<SearchPage/>, document.getElementById("root"));
.SearchPage {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.3);
transform: translateX(100%);
transition: 0.4s;
}
.SearchPage--active {
transform: translateX(0);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>
Вариант №2: CSS animation
class SearchPage extends React.Component {
constructor() {
super();
}
componentDidMount() {}
render() {
return(
<div className='SearchPage'></div>
)
}
}
ReactDOM.render(<SearchPage/>, document.getElementById("root"))
.SearchPage {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.3);
animation: slideIn 0.4s;
}
@keyframes slideIn {
from {
transform: translateX(100%);
}
to {
transform: translateX(0);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости