为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

函数式编程 2021-11-18 20:29:48
我有一个 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 没有一直转发到按钮本身。恐怕我有点失落,所以呼吁您的帮助!
查看完整描述

2 回答

?
临摹微笑

TA贡献1982条经验 获得超2个赞

只是想确保,您想要的是:当用户Enter在文本字段上键入时按下时,按钮将显示加载视觉效果,对吗?我认为您不必将 ref 传递给按钮组件,您可以将状态传递isLoadingShown到您的WaitingButton


等待按钮.js


 return (

        <div className={classes.buttonWrapper}>

            <Button 

                ref={this.props.innerRef}

                disabled={loading || disabled}

                onClick={this.handleClick}

                {...other}>

                <React.Fragment>

                    {children}

                    {this.props.isLoadingShown && this.buildLoader(loading, classes)}

                </React.Fragment>

            </Button>

        </div>

    );

然后在表单组件中


state = {

   isLoadingShown: false,

}


triggerClick() {

    this.setState({ isLoadingShown: true })

}


render(){

   ...

   <Paper>

       <TextField 

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

           label="A textbox!"

           fullWidth 

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

       <WaitingButton

           variant="contained"

           color="primary"

           isLoadingShown={this.state.isLoadingShown}

           onClick={(e) => {

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

           }}>

           Press enter in textbox!

       </WaitingButton>

   </Paper>

   ...

}

不要忘记isLoadingShown再次设置为falsecomponentWillUnmount


查看完整回答
反对 回复 2021-11-18
?
慕尼黑8549860

TA贡献1818条经验 获得超11个赞

我只是试图重现你的情况。我为它创建了一个代码沙盒。我想我发现了问题。看起来 React.forwardRef 只适用于 prop name forwardedRef 所以尝试在你的代码中将 innerRef 属性重命名为 forwardedRef 。


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

  forwardedRef={ref} {...props}

/>);

还有你的 render() 函数


<Button 

    ref={this.props.forwardedRef}

    disabled={loading || disabled}

    onClick={this.handleClick}

    ...

你可以用我的简化代码和盒子试试https://codesandbox.io/s/intelligent-cori-rb5ce


查看完整回答
反对 回复 2021-11-18
  • 2 回答
  • 0 关注
  • 445 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信