从父组件到子组件的到达点击处理程序不起作用

Posted

技术标签:

【中文标题】从父组件到子组件的到达点击处理程序不起作用【英文标题】:Reach Click handler from parent to child component is not working 【发布时间】:2021-11-30 05:08:30 【问题描述】:

我是 React 领域的新手,所以我不确定自己做错了什么。我在父组件中有一个点击处理程序,需要传递子组件的按钮元素。

父组件是'LogStatus'

import React,  Component  from 'react';
import DisplayMessage from './DisplayMessage'
class LogStatus extends React.Component 
    constructor(props) 
        super(props);
        this.state = 
            isLogin: true,
        
        this.btnChangeStatusClickHandler = this.btnChangeStatusClickHandler.bind(this);
    

    btnChangeStatusClickHandler() 
        this.setState(previousState =>
            previousState.isLogin = !this.state.isLogin,
        )
    

    render() 
        let statusMessage = '';
        if (this.state.isLogin === true) 
            statusMessage = 'Login';
        
        else 
            statusMessage = 'Logoff'
        
        return (
            <div>
                <DisplayMessage statusMessage=statusMessage loginStatusHandler=this.btnChangeStatusClickHandler />
            </div>
        );
    


export default LogStatus;

子组件是'DisplayMessage'

import React,  Component  from 'react';
class DisplayMessage extends Component 
    constructor(props) 
        super(props);
        this.state = 
            statusMessage: props.statusMessage,
            btnStatusClickHandler: props.loginStatusHandler,
        
    
    render() 
        let displayBtnMessage = '';
        if (this.state.statusMessage === 'Login') 
            displayBtnMessage = "Logoff";
        
        else 
            displayBtnMessage = 'Login';
        
        return (
            <div>
                <h3>Login Status: this.state.statusMessage</h3>
                <button onClick=this.state.btnStatusClickHandler>displayBtnMessage</button>
            </div>
        );
    


export default DisplayMessage;

工作代码供参考:

父组件是'LogStatus'

import React,  Component  from 'react';
import DisplayMessage from './DisplayMessage'
class LogStatus extends React.Component 
    constructor(props) 
        super(props);
        this.state = 
            isLogin: true,
            displayStatus: '',
        
        this.btnChangeStatusClickHandler =     this.btnChangeStatusClickHandler.bind(this);
    

    btnChangeStatusClickHandler() 
        this.setState(previousState => 
            if (this.state.isLogin === true) 
                return 
                    displayStatus: 'Login',
                    isLogin: !previousState.isLogin,
                
            
            else 
                return 
                    displayStatus: 'Logoff',
                    isLogin: !previousState.isLogin,
                
            
        )
    

    render() 
        return (
            <div>
                <DisplayMessage statusMessage=this.state.displayStatus loginStatusHandler=this.btnChangeStatusClickHandler />
            </div>
        );
    


export default LogStatus;

子组件是'DisplayMessage'

import React,  Component  from 'react';
class DisplayMessage extends Component 
    render() 
        const  statusMessage, loginStatusHandler  = this.props;
        let displayBtnMessage = '';
        if (statusMessage === 'Login') 
            displayBtnMessage = "Logoff";
        
        else 
            displayBtnMessage = 'Login';
        
        return (
            <div>
                <h3>Login Status: statusMessage</h3>
                <button onClick=loginStatusHandler>displayBtnMessage</button>
            </div>
        );
    


export default DisplayMessage;

【问题讨论】:

【参考方案1】:

您需要对代码进行两次更改;

1。确保您的点击处理程序的上下文是正确的

btnChangeStatusClickHandler当前是你的类组件的一个方法。但是,调用此函数将使用全局上下文 (this)。所以this.setState 将不起作用。您可以通过将方法转换为箭头函数成员来解决此问题:

改变

    btnChangeStatusClickHandler() 
        this.setState(previousState =>
            previousState.isLogin = !this.state.isLogin,
        )
    

收件人

    btnChangeStatusClickHandler = () => 
        this.setState(previousState =>
            previousState.isLogin = !this.state.isLogin,
        )
    

2。不要在状态中委派您的点击处理程序

不需要(也不推荐)在组件状态下委派您的点击处理程序和其他道具。您应该始终直接使用来自props 的事件处理程序和其他属性,以便它可以处理更改。

import React,  Component  from 'react';

class DisplayMessage extends Component 
    render() 
        const  statusMessage, loginStatusHandler  = this.props;
        let displayBtnMessage = '';

        if (statusMessage === 'Login') 
            displayBtnMessage = "Logoff";
        
        else 
            displayBtnMessage = 'Login';
        

        return (
            <div>
                <h3>Login Status: statusMessage</h3>
                <button onClick=loginStatusHandler>displayBtnMessage</button>
            </div>
        );
    


export default DisplayMessage;

【讨论】:

谢谢@Chris。你提出的建议很有帮助。虽然我已经修改了几行代码以修复获得正确的输出。

以上是关于从父组件到子组件的到达点击处理程序不起作用的主要内容,如果未能解决你的问题,请参考以下文章

从子组件到父组件的绑定字符串字段不起作用

将状态作为道具传递给子组件不起作用

与 debounce、event.persist() 和在父组件中存储值一起使用时,输入不起作用

如何将 Angular 5 中的点击数据从父组件传递到子组件?

Angular中从父组件到子组件的数据共享

React Native:组件上的 onPress 不起作用