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

问题描述 投票:9回答:3

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

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

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

那么React上点击切换一个类应用,但是失去了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;
    }
}
javascript css3 reactjs css-transitions
3个回答
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干杯:)


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>
    }
}

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>
    }
}

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

干杯!

© www.soinside.com 2019 - 2024. All rights reserved.