Mar*_*rat 4 reactjs react-transition-group
更新:
对于那些面临同样问题的人:我在 ReactTransitionGroup 的 git 页面上发现了一个类似的问题,其中有解决方案:https : //github.com/reactjs/react-transition-group/issues/182。
老实说,90% 的解决方案让我印象深刻,我根本不明白,这是唯一对我有意义的部分(取自React TransitionGroup 和 React.cloneElement 不发送更新的道具这与 git 问题相关):
传递道具给孩子? 现在的问题是,为什么没有更新的道具被传递给离开元素?那么,它会如何获得道具呢?道具从父组件传递给子组件。如果您查看上面的示例 JSX,您可以看到离开元素处于分离状态。它没有父级,它只是被渲染,因为 将它存储在它的状态中。
我必须进一步研究和了解父组件和子组件的通信方式。我仍然是 Web 开发的新手,但事情正在慢慢开始变得有意义。
------------------
最初提出的问题:
当您尝试通过 React.cloneElement 将状态注入到您的子组件时,离开组件不是这些子组件之一。
我有一个包含导航菜单和嵌套在开关容器之间的路由的小应用程序。每次单击导航项时,我都会检查索引是更高还是更低以相应地设置动画状态(左或右),然后存储单击的导航项的新索引。
每次我切换路线时,应用的动画要么是淡入淡出,要么是淡入淡出。现在这一切正常,但唯一的问题是当类从左向右切换时,应用的 EXIT 动画使用给定的前一个类。
我理解为什么会发生这种情况,这是因为使用的退出类是最初设置的,当新类仅应用于第二次更改时,新的退出才会生效。转换文档非常有限,我找不到任何东西。
const { Component } = React;
const { TransitionGroup, CSSTransition } = ReactTransitionGroup;
const { HashRouter, Route, NavLink, Switch, withRouter } = ReactRouterDOM;
var icons = [
{icon: 'far fa-address-book active', path: '/'},
{icon: 'fab fa-linkedin', path: '/linked'},
{icon: 'fas fa-gamepad', path: '/hobbies'}
];
const Nav = props => {
return (
<div className="nav">
<ul>
{
icons.map((icon, index) => {
return (
<li
key={index}
onClick={() => props.clicked(index)}
className={props.active == index ? 'active' : false}>
<NavLink to={icon.path} className="NavLink">
<i className={icon.icon} key={icon.icon}></i>
</NavLink>
</li>
);
})
}
</ul>
</div>
);
}
class App extends Component {
constructor(props) {
super(props);
this.state = {
currentViewIndex: 0,
animationDirection: 'right'
}
this.setIndex = this.setIndex.bind(this);
}
setIndex(index){
const animationDirection = index < this.state.currentViewIndex ? 'left' : 'right';
this.setState({currentViewIndex: index, animationDirection});
}
render () {
const { location } = this.props;
return (
<div className="container">
<Nav active={this.state.currentViewIndex} clicked={() => this.setIndex()} />
<TransitionGroup>
<CSSTransition
key={location.pathname}
classNames={`fade-${this.state.animationDirection}`}
timeout={1000}>
<Switch location={location}>
<Route exact path="/" render={() => <h1>Home</h2>} />
<Route path="/linked" render={() => <h1>Linked</h2>} />
<Route path="/hobbies" render={() => <h1>Hobbies</h2>} />
</Switch>
</CSSTransition>
</TransitionGroup>
</div>
);
}
}
const AppWithRouter = withRouter(App);
ReactDOM.render(<HashRouter><AppWithRouter /></HashRouter>, document.querySelector('#root'));
Run Code Online (Sandbox Code Playgroud)
应用于过渡的 CSS 类:
.fade-left-enter {
position: unset;
transform: translateX(-320px);
}
.fade-left-enter.fade-left-enter-active {
position: unset;
transform: translateX(0);
transition: transform .5s ease-in;
}
.fade-left-exit {
position: absolute;
bottom: 0;
transform: translateX(0);
}
.fade-left-exit.fade-left-exit-active {
transform: translateX(320px);
transition: transform .5s ease-in;
}
.fade-right-enter {
position: unset;
transform: translateX(320px);
}
.fade-right-enter.fade-right-enter-active {
position: unset;
transform: translateX(0);
transition: transform .5s ease-in;
}
.fade-right-exit {
position: absolute;
bottom: 0;
transform: translateX(0);
}
.fade-right-exit.fade-right-exit-active {
transform: translateX(-320px);
transition: transform .5s ease-in;
}
Run Code Online (Sandbox Code Playgroud)
您的问题的原因是现有组件已经分离,因此没有得到任何更新。你可以在这里找到对你的问题的很好的解释。
你可以使用 prop childFactory from<TransitionGroup>来解决这个问题:
子工厂
您可能需要在子项退出时对其应用响应式更新。这通常是通过使用 cloneElement 来完成的,但是在退出子元素的情况下,该元素已经被删除并且消费者无法访问。
如果您确实需要在离开时更新孩子,您可以提供一个 childFactory 来包装每个孩子,即使是离开的孩子。
在渲染方法中尝试以下代码更改:
render () {
const { location } = this.props;
const classNames = `fade-${this.state.animationDirection}`; // <- change here
return (
<div className="container">
<Nav active={this.state.currentViewIndex} clicked={() => this.setIndex()} />
<TransitionGroup
childFactory={child => React.cloneElement(child, { classNames })} // <- change here
>
<CSSTransition
key={location.pathname}
classNames={classNames} // <- change here
timeout={1000}
>
<Switch location={location}>
<Route exact path="/" render={() => <h1>Home</h2>} />
<Route path="/linked" render={() => <h1>Linked</h2>} />
<Route path="/hobbies" render={() => <h1>Hobbies</h2>} />
</Switch>
</CSSTransition>
</TransitionGroup>
</div>
);
Run Code Online (Sandbox Code Playgroud)
}
| 归档时间: |
|
| 查看次数: |
2185 次 |
| 最近记录: |