【问题标题】:React toggle class + CSS transitions, not working... why?反应切换类+ CSS过渡,不工作......为什么?
【发布时间】:2018-03-04 12:40:13
【问题描述】:

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

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

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

那么 React on click 来切换类应用,但失去了 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;
    }
}

【问题讨论】:

  • 它必须完全替换 DOM 元素。当您打开 DevTools 并切换菜单时,整个 DOM 元素会闪烁,还是仅闪烁其 class 属性?
  • 我赌的是路由器库。如果您不将ProjectsRouteRouter 包装在一起,您能否尝试一下它是否有效?还有你使用哪个 react-router 版本?
  • 您的代码没有显示 CSS 过渡组的导入? import { CSSTransitionGroup } from 'react-transition-group' .... 过渡和反应存在一些问题(这就是原始插件发布的原因).. 有一篇很好的文章 here

标签: javascript css reactjs css-transitions


【解决方案1】:

这是因为 react-router 将每个路由视为 switch 语句中的一个案例,而 &lt;Route /&gt; 组件中的 path 是该案例的 key。当路径改变时,组件被完全卸载。因此,您看不到 CSS 转换,因为它的 DOM 不再存在。

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

我希望这会有所帮助。

还有一个关于 youtube 的精彩演讲大约 30 分钟,讨论如何在路由 https://www.youtube.com/watch?v=S3u-ccn4PEM Cheers 中做出非常好的动画 :)

【讨论】:

    【解决方案2】:

    确实,问题在于react-router 正在卸载您的组件并使用新类再次安装它,在此过程中丢失了 CSS 转换。要解决此问题,只需在&lt;Route&gt; 组件上使用render 而不是 component

    至于为什么会这样,来自react-router 文档:

    您可以传入一个在位置匹配时调用的函数,而不是使用组件属性为您创建一个新的 React 元素。 render prop 接收与组件 render prop 相同的所有路由 prop。

    更详细的解释可以阅读问题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,它似乎工作正常!

    干杯!

    【讨论】:

      【解决方案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>
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-03-06
        • 1970-01-01
        • 2015-09-01
        • 1970-01-01
        • 2021-04-05
        • 1970-01-01
        • 2020-11-25
        • 1970-01-01
        相关资源
        最近更新 更多