在 React 中,如何从不同组件的事件处理程序触发自定义按钮的点击事件?

我有一个 React 应用程序,它的界面使用Material UI。我创建了一个自定义按钮组件,它为默认的 Material UI 按钮设置样式并使用 redux。


render()我的按钮组件的功能如下所示:


        return (

            <div className={classes.buttonWrapper}>

                <Button 

                    ref={this.props.innerRef}

                    disabled={loading || disabled}

                    onClick={this.handleClick}

                    {...other}>

                    <React.Fragment>

                        {children}

                        {this.buildLoader(loading, classes)}

                    </React.Fragment>

                </Button>

            </div>

        );

我想要的是能够在页面上包含这个按钮,并让 UI 通过点击以外的其他方式触发它的点击事件。例如,在登录表单上,我希望当前关注密码文本框的用户能够通过按 Return/Enter 键触发按钮单击。


我确定我需要在 React 中使用转发引用的概念,但我对 React 还很陌生,无法让它工作。你可以在我的按钮上看到我已经定义了一个ref集合this.props.innerRef。我的按钮组件(称为WaitingButton)是这样导出的:


const withInnerRef = React.forwardRef((props, ref) => <WaitingButton 

  innerRef={ref} {...props}

/>);


var component = withStyles(styles)(withInnerRef);


export default connect(mapStateToProps, mapDispatchToProps)(component);


然后我将此按钮添加到这样的表单中:


    <Paper>

        <TextField 

            style={{marginBottom: '8px'}}

            label="A textbox!"

            fullWidth 

            onKeyPress={(e) => { if (e.key === "Enter") this.triggerClick(); }} />

        <WaitingButton 

            ref={this.submitButton}

            variant="contained"

            color="primary"

            onClick={(e) => {

                console.log('Button clicked :)', e.target);

            }}>

            Press enter in textbox!

        </WaitingButton>

    </Paper>

请参阅我已分配按钮,ref并在此页面的构造函数中使用this.submitButton = React.createRef();


最后triggerClick看起来像这样:


    triggerClick() {

        console.log('CLICK', this.submitButton.current);

        this.submitButton.current.click();

    }

当我在文本框中按 Enter 键时,我可以检查分配给的值,this.submitButton.current并可以看到它是connect我包裹按钮的 Redux对象。但是,我也得到了错误this.submitButton.current.click is not a function,很明显,ref 没有一直转发到按钮本身。


恐怕我有点失落,所以呼吁您的帮助!


函数式编程
浏览 446回答 2
2回答

临摹微笑

只是想确保,您想要的是:当用户Enter在文本字段上键入时按下时,按钮将显示加载视觉效果,对吗?我认为您不必将 ref 传递给按钮组件,您可以将状态传递isLoadingShown到您的WaitingButton等待按钮.js&nbsp;return (&nbsp; &nbsp; &nbsp; &nbsp; <div className={classes.buttonWrapper}>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <Button&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ref={this.props.innerRef}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; disabled={loading || disabled}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; onClick={this.handleClick}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {...other}>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <React.Fragment>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {children}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {this.props.isLoadingShown && this.buildLoader(loading, classes)}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </React.Fragment>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </Button>&nbsp; &nbsp; &nbsp; &nbsp; </div>&nbsp; &nbsp; );然后在表单组件中state = {&nbsp; &nbsp;isLoadingShown: false,}triggerClick() {&nbsp; &nbsp; this.setState({ isLoadingShown: true })}render(){&nbsp; &nbsp;...&nbsp; &nbsp;<Paper>&nbsp; &nbsp; &nbsp; &nbsp;<TextField&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;style={{marginBottom: '8px'}}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;label="A textbox!"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;fullWidth&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;onKeyPress={(e) => { if (e.key === "Enter") this.triggerClick(); }} />&nbsp; &nbsp; &nbsp; &nbsp;<WaitingButton&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;variant="contained"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;color="primary"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;isLoadingShown={this.state.isLoadingShown}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;onClick={(e) => {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;console.log('Button clicked :)', e.target);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}}>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Press enter in textbox!&nbsp; &nbsp; &nbsp; &nbsp;</WaitingButton>&nbsp; &nbsp;</Paper>&nbsp; &nbsp;...}不要忘记isLoadingShown再次设置为falsecomponentWillUnmount

慕尼黑8549860

我只是试图重现你的情况。我为它创建了一个代码沙盒。我想我发现了问题。看起来 React.forwardRef 只适用于 prop name forwardedRef 所以尝试在你的代码中将 innerRef 属性重命名为 forwardedRef 。const withInnerRef = React.forwardRef((props, ref) => <WaitingButton&nbsp;&nbsp; forwardedRef={ref} {...props}/>);还有你的 render() 函数<Button&nbsp;&nbsp; &nbsp; ref={this.props.forwardedRef}&nbsp; &nbsp; disabled={loading || disabled}&nbsp; &nbsp; onClick={this.handleClick}&nbsp; &nbsp; ...你可以用我的简化代码和盒子试试https://codesandbox.io/s/intelligent-cori-rb5ce
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript