反应切换类+ CSS转换,不工作......为什么?

时间:2017-09-22 20:58:17

标签: javascript css3 reactjs css-transitions

我一直在使用类控制打开/关闭行为,而CSS过渡效果很好。我已经在其他组件上使用了这个,没问题,但由于某种原因,在这种情况下,同样的方法让我失望......

打开/关闭行为附加(我看到与背景颜色和translateY的结束差异)但是CSS转换本身丢失了...任何想法为什么我失去了我的CSS过渡但其他一切都按预期工作?

注意,当我使用开发人员工具手动切换打开/关闭的类时,它工作得很好! CSS过渡开始了!

那么,当点击切换一个类申请但是失去CSS过渡时,反应是什么?

class Projects extends React.Component {
    /* constructor, etc... */
    render() {
        return (
            <div className="projects-nav-container">
                <div className="center title monospace" onClick={this.props._toggleProjectNav} id="Menu">Menu</div>
                <ul className={`projects-nav ${this.props._isProjectNavOpen ? 'open' : 'closed'}`}>
                    { PROJECTS.map((project, index) => 
                    <li key={index} >
                         <p>project here</p>
                    </li>
                    ) }
                </ul>
            </div>
        );
    }
}

App.js看起来像这样:

class App extends React.Component {
    constructor() {
        super();
        this.state = {
            _isProjectNavOpen: true
        }
        this._toggleProjectNav = this._toggleProjectNav.bind(this);
    }
    _toggleProjectNav() {
        this.setState(prevState => ({
            _isProjectNavOpen: !prevState._isProjectNavOpen,
        }));
    }
    render() {
        <div>
            <Router>
                <Route path="/projects" component={(props, state, params) => 
                    <Projects 
                        _toggleProjectNav={this._toggleProjectNav}
                        _isProjectNavOpen={this.state._isProjectNavOpen} 
                    {...props} />} />
            </Router>
        </div>
    }
}

SCSS:

.projects-nav {
    @include transition(all $transition_speed ease);
    &.open {
        @include transform(translateY(0));
        background: red
    }
    &.closed {
        @include transform(translateY(-100vh));
        background: green;
    }
}

3 个答案:

答案 0 :(得分:12)

这是因为react-router在switch语句中将每个路由都视为一个案例,并且path组件中的<Route />是该案例的key。更改路径后,组件将完全卸载。因此,您看不到CSS过渡,因为它的DOM不再存在。

如果要使用react-router制作动画。您需要使用一个名为react-transition-group的react实用程序库。这是react-router作者的详细示例,您可以遵循。 React Router Animation Example

我希望这会有所帮助。

在youtube上大约有30分钟的精彩演讲,内容涉及如何在路由https://www.youtube.com/watch?v=S3u-ccn4PEM的欢呼声中做出非常好的动画:)

答案 1 :(得分:3)

更改键必须更新元素。

尝试此代码:

class App extends React.Component {
    constructor() {
        super();
        this.state = {
            _isProjectNavOpen: true,
            _ProjectsKey: 1,
            _RouteKey: 1
        }
        this._toggleProjectNav = this._toggleProjectNav.bind(this);
    }
    _toggleProjectNav() {
        this.setState(prevState => ({
            _isProjectNavOpen: !prevState._isProjectNavOpen,
            _ProjectsKey: prevState._ProjectsKey + 1,
            _RouteKey: prevState._RouteKey + 1
        }));
    }
    render() {
        <div>
            <Router>
                <Route key={this.state._RouteKey} path="/projects" component={(props, state, params) => 
                    <Projects 
                        _toggleProjectNav={this._toggleProjectNav}
                        _isProjectNavOpen={this.state._isProjectNavOpen} 
                        key={this.state._ProjectsKey} 
                    {...props} />} />
            </Router>
        </div>
    }
}

答案 2 :(得分:3)

实际上,问题在于react-router正在卸载您的组件,并使用新的类再次进行安装,从而失去了CSS转换过程。要解决此问题,只需在render组件上使用component中的<Route> 代替

根据react-router文档,了解其工作原理:

  

除了使用组件prop为您创建新的React元素外,您还可以传递一个在位置匹配时要调用的函数。渲染道具接收与组件渲染道具相同的所有路线道具。

有关详细说明,您可以阅读问题react router difference between component and render

总而言之,App.js应该如下所示:

class App extends React.Component {
    constructor() {
        super();
        this.state = {
            _isProjectNavOpen: true
        }
        this._toggleProjectNav = this._toggleProjectNav.bind(this);
    }
    _toggleProjectNav() {
        this.setState(prevState => ({
            _isProjectNavOpen: !prevState._isProjectNavOpen,
        }));
    }
    render() {
        <div>
            <Router>
                <Route path="/projects" render={(props, state, params) => 
                    <Projects 
                        _toggleProjectNav={this._toggleProjectNav}
                        _isProjectNavOpen={this.state._isProjectNavOpen} 
                    {...props} />} />
            </Router>
        </div>
    }
}

我使用render创建了一个CodeSandbox,它似乎可以正常工作!

干杯!