在ReactJS Prop变更之间平滑过渡

nat*_*rek 5 reactjs

有两个按钮可以切换项目的布局。当单击任一按钮时,我希望该项目淡出,更改然后再淡入。

使用ReactJS,我遇到了两个问题:

  1. 使用componentDidUpdate触发“淡入”事件会导致循环。不断改变状态会再次触发componentDidUpdate

  2. 使用componentWillReceiveProps允许我更新元素上的类以使其淡出,但它也立即更改布局。我需要将更改延迟到看不见为止。

有什么想法吗?我搞错了吗?

(下面的代码,但是在JSFiddle中可以使用的Stack版本中有些问题:https ://jsfiddle.net/nathanziarek/69z2wepo/15009/ )

var Hello = React.createClass({
    getInitialState: function() {
    	return { visible: " x-hidden" };
    },
    render: function() {
        return <div className={"hello" + this.state.visible}>Hello {this.props.name}</div>;
    },
    componentDidMount: function(){
    	this.setState({ visible: "" })
    },
    componentWillReceiveProps: function(){
    	// The item is changing, make it invisible
        // Wait until it's done being invisible before changing
        // anything?
    	this.setState({ visible: " x-hidden" })
    },
    componentDidUpdate: function(){
    	// The item has changed, make it visible
        // Setting anything here causes this function
        // to get called again, creating a loop
    	// this.setState({ visible: "" })
    }
});

var Button = React.createClass({
    render: function() {
        return <button onClick={this.handleClick}>{this.props.label}</button>;
    },
    handleClick: function() {
    	React.render(
        	<span>
            	<Button label="Universe"/>
                <Button label="World"/>
                <Hello name={this.props.label} />
            </span>, 
            document.getElementById('container')
        );
    }
});
 
React.render(
    <span>
        <Button label="Universe"/>
        <Button label="World"/>
        <Hello name="_______" />
    </span>, 
    document.getElementById('container')
);
Run Code Online (Sandbox Code Playgroud)
.hello {
    opacity: 1;
    transition: 300ms opacity linear;
    -webkit-transition: 300ms opacity linear;
}

.x-hidden { opacity: 0 }
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.1/JSXTransformer.js"></script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.1/react-with-addons.js"></script>

<script src="https://facebook.github.io/react/js/jsfiddle-integration.js"></script>

<div id="container">
  <!-- This element's contents will be replaced with your component. -->
</div>
Run Code Online (Sandbox Code Playgroud)

Joh*_*and 1

最简单的方法是将两者都显示在屏幕上,然后完全使用 css 进行淡入淡出,并且除了放置适当的类之外,基本上完全从过程中省略 React。

如果您在它们之间淡入淡出,则无论如何您都需要两组内容。反过来,这意味着没有理由不在文档中包含这些内容,这又意味着它只是 CSS 隐藏/显示的愚蠢行为,并且不需要任何类型的 React 生命周期内容。

你试图让 React 处理太多东西,这让事情变得过于复杂。

支持CSS:

#foo span { 
  opacity: 0; 
  position: absolute; 
  top: 0; left: 0; bottom: 0; right: 0; 
  transition: all 0.5s ease; 
}

#foo span.show { 
  opacity: 1; 
}
Run Code Online (Sandbox Code Playgroud)

然后是相关的React:

var Foo = react.createComponent({ 

  render: function() { 

    var showKey = this.props.showKey,
        Things = {
          a: 'Apple',
          b: 'Bear',
          c: 'Cold inevitable doom'
        };

    return (
      <div id="foo">
        { Things.map(X,k) { 
          return <span class={(showKey === k)? 'show':undefined}>{X}</span> 
        }}
      </div>
    );

  }

});
Run Code Online (Sandbox Code Playgroud)

您会发现,当您切换该控件的 showKey 时,它将根据需要淡入和淡出其相关内容。