Анимация перехода на другую страницу React

146
29 июня 2019, 11:50

Пытаюсь сделать анимацию перехода на другую страницу следующим образом: Для начала я обернул в 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;

Answer 1

Дело в том что 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>

READ ALSO
Как выполнить функцию после нескольких AJAX ( количество ajax неизвестно )?

Как выполнить функцию после нескольких AJAX ( количество ajax неизвестно )?

Как после получения ответов сервера от всех AJAX, запустить функцию? Количество AJAX запросов неизвестно, всегда может быть разнымНо нужно дождаться...

116
Смена цвета меню JavaScript

Смена цвета меню JavaScript

Как сделать, чтобы при нажатии на любое подменю, цвет меню менялся?

129
owlCarousel карусель перенос видимых элементов

owlCarousel карусель перенос видимых элементов

Как можно сделать перенос видимых элементов owlCarousel карусель?

130
Кнопка обратного действия на JavaScript:

Кнопка обратного действия на JavaScript:

Всем привет, есть разметка и js код, в разметке textarea и 2 кнопки - перевод и показать исходный текстВ js коде есть скрипт, который при нажатии на копку...

146