基于计时器

时间:2016-01-08 10:50:34

标签: javascript reactjs

这是我的问题:当用户点击提交按钮时,如果提交没有成功(即由于网络问题),我想从页面顶部滑动横幅。

横幅显示2秒后,我希望它缩回并退出视图。

以下是我的代码片段:

export default class Base extends React.Component {
    ...

    renderErrMsg = () => {
        if(this.props.errMsg){
            return (
                <div className="errMsg">
                    {this.props.errMsg}
                </div>
            )
        }
    }

    render(){
        return(
            <div>
                {this.renderErrMsg()}
                ...
            <div>
        )
    }
}

我尝试用#errMsg包裹ReactCSSTransitionGroup,但它给了我一个错误:

  

warning.js:45警告:React.createElement:type不应为null,undefined,boolean或number。它应该是一个字符串(对于DOM元素)或一个ReactClass(对于复合组件)。检查Base。警告

的渲染方法      

未捕获错误:不变违规:元素类型无效:预期字符串(对于内置组件)或类/函数(对于复合组件)但得到:undefined。检查Base的呈现方法。

更新:@Ted绝对指出了正确的解决方案。在他的解决方案中,创建了一个状态来镜像存储在道具中的值。我意识到不需要使用componentWillReceiveProps而不是componentWillUpdate来创建状态变量:

componentWillReceiveProps(nextProps) {
    if (nextProps.application.errorMessage){
        setTimeout(() => {
            this.props.dispatch(removeErrMsg())
        }, 3000)
    }
}

我必须编写removeErrMsg操作,以便dispatch可以在商店显示后清除商店中的错误消息。

我犯的错误:

  1. 我的导入声明错误:我有import { ReactCSSTransitionGroup } from 'react/addons',但应该是import ReactCSSTransitionGroup from 'react-addons-css-transition-group'

  2. 呈现错误消息时,ReactCSSTransitionGroup部分应位于render()方法内,而不是renderErrMsg方法。 renderErrMsg会返回要设置动画的内容,但不应该返回TransitionGroup。否则,就不会有任何动画。因为当没有错误消息时,整个errMsg div和TransitionGroup变为空,错误消息div将消失而不是撤消。

1 个答案:

答案 0 :(得分:0)

首先,您应该将道具转移到组件状态,以便在延迟后将其清除。使用componentWillReceiveProps生命周期方法更新状态并在需要延迟后清除它。对于转换,您需要在key元素的子元素上设置<Transition>属性(因为您只为一个子项目键设置动画可以是任何内容)。此外,您的renderErrMsg()方法应始终返回一个值,因此请在if语句中添加else return null

这是一个有效的演示:http://codepen.io/teodragovic/pen/KVqgYg?editors=011

JSX:

const Transition = React.addons.CSSTransitionGroup;

const Example = React.createClass({

    getInitialState() {
        return {
            error: null
        };
    },

    render() {
        return (
            <div>
                <button onClick={this.handleClick}>submit</button>
                <Inner error={this.state.error} />
            </div>
        );
    },

    handleClick() {
        this.setState({ error: 'error' });
    }

});

const Inner = React.createClass({

    getDefaultProps() {
        return {
            error: null
        };
    },

    getInitialState() {
        return {
            error: this.props.error
        };
    },

    componentWillReceiveProps(nextProps) {
        if (nextProps.error) {
            this.setState({ error: nextProps.error });
            const timer = setTimeout(() => {
                clearTimeout(timer);
                this.setState({ error: null });
            }, 3000);
        }
    },

    render() {
        return (
            <div>
                <Transition
                    component="div"
                    transitionName="item"
                >
                    {this.renderErrMsg()}
                </Transition>
            </div>
        );
    },

    renderErrMsg() {
        if (this.state.error) {
            return (
                <div className="errMsg" key={1}>
                    {this.state.error}
                </div>
            );
        } else {
            return null;
        }
    }


});

React.render(
    <Example />,
    document.getElementById('example')
);

的CSS:

.errMsg {
    padding: 20px;
    border: 1px solid blue;
    text-align: center;
    position: absolute;
    top: 50%;
    left: 0;
    right: 0;
    transform: translateY(-50%);
}

.item-enter {
    top: -50%;
    transition: all .5s ease-out;
}

.item-enter-active {
    top: 50%;
}

.item-leave {
    top: 50%;
    transition: all .5s ease-in;
}

.item-leave-active {
    top: -50%;
}