javascript - 如何设置显示:block and transition opacity at the same time in React?

标签 javascript css reactjs css-transitions jsx

我在 JSX 中定义了一个背景层元素,它最初设置了 display:none:

<div id="naviBG" style={naviBGStyleClone} role="button" onClick={this.onCloseClicked} />

风格:

const naviBGStyle = {
  display: 'none',
  opacity: 0,
  transition: 'opacity 0.4s ease',
};

单击时,我希望图层平滑消失或使用 css 中定义的过渡重新出现。在 render() 中,我检查该元素是应该显示还是隐藏:

渲染()

const naviBGStyleClone = Object.assign({}, naviBGStyle);
if (this.props.status === 'closed') {
  naviBGStyleClone.display = 'none';
  naviBGStyleClone.opacity = 0;
} else {
  naviBGStyleClone.display = 'block';
  naviBGStyleClone.opacity = 1;
}

return (
    <div id="naviBG" style={naviBGStyleClone} role="button" onClick={this.onCloseClicked} />
);

现在,这有点像元素将被显示/隐藏,但它会在没有设置不透明度的过渡动画的情况下弹出。

通常我会使用类似 requestAnimationFrame 的东西来解决这个问题,如下所示:

render() 与 raf:

const naviBGStyleClone = Object.assign({}, naviBGStyle);
if (this.props.status === 'closed') {
  naviBGStyleClone.display = 'none';
  if (typeof window !== 'undefined') {
    window.requestAnimationFrame(() => {
      naviBGStyleClone.opacity = 0;
    });
  }
} else {
  naviBGStyleClone.display = 'block';
  if (typeof window !== 'undefined') {
    window.requestAnimationFrame(() => {
      naviBGStyleClone.opacity = 1;
    });
  }
}

return (
    <div id="naviBG" style={naviBGStyleClone} role="button" onClick={this.onCloseClicked} />
);

但这在 React 中不起作用,因为它会导致样式在 render() 已经完成后被修改。

那么,在 React 中执行此操作的正确方法是什么?

最佳答案

因为转换不会在通过display: none 隐藏的元素上触发,您可以连续两次调用setState,一次触发显示更改,然后再次触发不透明度变化,并以相反的顺序使其淡出然后隐藏。

class App extends React.Component {
  state = { display: 'none', opacity: 0 }

  toggle = () => {
    if (this.state.display === 'none') {
      this.setState({ display: 'block' })
      setTimeout(() =>
        this.setState({ opacity: 1 }), 10 // something very short
      )
    }
    if (this.state.display === 'block') {
      this.setState({ opacity: 0 })
      setTimeout(() =>
        this.setState({ display: 'none' }), 300 // same as transition time
      )
    }
  }

  render() {
    return (
      <div>
        <button onClick={this.toggle}>toggle</button>        
        <div 
          style={{ 
            transition: 'opacity 0.3s ease',
            opacity: this.state.opacity,
            display: this.state.display
          }} 
        />
      </div>
    )
  }
}

Example on codepen

我还鼓励您查看 React Motion 以处理更复杂的转换,就像您可能使用 requestAnimationFrame

https://github.com/chenglou/react-motion

关于javascript - 如何设置显示:block and transition opacity at the same time in React?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44392171/

相关文章:

javascript - WebStorm,使用 Node Supervisor(所以每次代码更改后不必重新启动)?

javascript - 有什么方法可以在不完全重新处理/重新编码的情况下为我的迷宫添加边界?

css - 尝试创建具有动态内容的无表控件

javascript - 无法使用 ramda 读取未定义的属性 'setState'

javascript - react 警告 : Received `true` for a non-boolean attribute `my-optional-property`

javascript - ReactJS 在表外渲染 tbody 数据

javascript - 如何使用lodash按键合并两个不同大小的对象数组

javascript - 如何使过滤后的输入能够在其中进行编辑,而不是在最后进行?

asp.net - 从 iFrame 重定向父窗口

javascript - css 动画完成后使用 jquery 淡入页面