ReactJS - 在渲染期间调用按钮onClick

时间:2017-01-02 14:57:56

标签: javascript reactjs ecmascript-6

我有一张type="range"的表单。现在我想添加3个按钮来更改表单所具有的相同值。出于某种原因,onClick事件按钮似乎在调用渲染函数时被重复调用。

这是我的组成部分:

class Slider extends Component {
    constructor(props) {
        super(props);

        this.handleChange = this.handleChange.bind(this);
        this.handleButton = this.handleButton.bind(this);
    }

    handleChange() {
        this.props.onSetCountdown(parseInt(this.refs.seconds.value, 10));
    }

    handleButton(value) {
        this.props.onSetCountdown(parseInt(value, 10));
    }

    render() {
        return(
            <div>
                <form className={styles.ttSlider} ref="form">
                    <input max="480" min="60" name="slider" onChange={this.handleChange} ref="seconds" type="range" value={this.props.totalSeconds}/>
                    <button onClick={this.handleButton(60)}>1min</button>
                    <button onClick={this.handleButton(180)}>3min</button>
                    <button onClick={this.handleButton(300)}>5min</button>
                </form>
            </div>
        )
    }
}

Slider.propTypes = {
    totalSeconds: React.PropTypes.number.isRequired,
    onSetCountdown: React.PropTypes.func.isRequired
};

这是来自父组件:

handleSetCountdown(seconds) {
        this.setState({
            count: seconds
        });
    }

从父组件渲染:

<Slider totalSeconds={count} onSetCountdown={this.handleSetCountdown}/>

这是我得到的错误:

  

警告:setState(...):在现有状态期间无法更新   过渡(例如在render或其他组件内   构造函数)。渲染方法应该是道具的纯函数   州;构造函数的副作用是反模式,但可以移动   到componentWillMount

对我来说,这看起来像onClick按钮在组件仍在渲染时被调用。我做错了什么?

2 个答案:

答案 0 :(得分:9)

这是因为您不是将函数传递给事件onClick,而是直接调用该函数。

尝试这样做:

<button onClick={() => { this.handleButton(60)}}>1min</button>
<button onClick={() => { this.handleButton(180)}}>3min</button>
<button onClick={() => { this.handleButton(300)}}>5min</button>

在这里找到答案:React onClick function fires on render

希望它有所帮助!

答案 1 :(得分:2)

如果你不想出于任何原因使用anon函数,第二种方法是直接在render函数中使用bind。然后你可以删除构造函数中的行:)

<button onClick={this.handleButton.bind(this, 60)}>1min</button>