首页 > 解决方案 > React/Next.js:从父级传递给子级的方法在父级或子级中执行?

问题描述

当我传递父组件中定义的方法时,我有点困惑,即将父组件的视图更改为子组件(例如,子组件中的按钮),当我单击按钮时在子组件上,来自父组件的方法是在父类(因此在父视图上)还是在子类(然后在子视图上)执行?

假设我想在单击子类中的按钮时在父类上显示一条警报消息,我猜该警报消息将显示在父类上。

但是是否也可以将父组件中定义的方法传递给子组件,然后更改子组件中的某些视图?

编辑:我举一个例子来说明我的问题:

我有一个组件要在父类中有条件地呈现:我通过 onShowAlert 方法在父组件上显示警报

if (this.state.alleAnzeigen.length > 0) {
      anzeigenListe = (
        <AnzeigenComponent 
          anzeigenArray={this.state.alleAnzeigen} 
          onClickAlert={this.onShowAlert}
          onButtonFinish={this.finishDocumentHandler}
        />
      ) 

在我的 AnzeigenComponent 中,我将方法传递给 Anzeige 组件,首先,我有 onClickalert={() => props.onClickAlert} 没有 (),但是,在我的 Parent 中,该方法当时没有执行。

const anzeigenArray = (props) => {
    return props.anzeigenArray.map((anzeige,index) => (      
        <li className="mainList" key={anzeige.id} style={{padding: "10px"}} >
            <Anzeige 
              anzeige={anzeige} 
              key={anzeige.id}
              index={index}  
              onClickalert={() => props.onClickAlert()}
              onButtonfinish={() => props.onButtonFinish(anzeige,index)}
            />
        </li>
    ))
}

export default anzeigenArray;

然而,我的子组件“Anzeige”是一个更大的有状态组件类:当我单击 singleAnzeige 渲染函数中的按钮时,我执行 props.onClickalert()-> 我作为道具传递下来的方法。但是,该方法没有做任何事情,除非我已经在上面提到的组件中使用括号“()”执行了该方法,我只是想知道,为什么会这样?是否存在子组件限制,我只能将方法向下传递 2 个级别左右,以便它仍然有效?

import React, {Component} from 'react';
import DubletteComponent from '../components/DubletteComponent';

import { Button, Alert } from 'reactstrap';
import { Container, Row, Col } from 'reactstrap';


class Anzeige extends Component {     
    constructor(props) {
        super(props);
    }


    singleAnzeige = (props) => {
        // let newText = this.htmlspecialchars_decode("71065 Sindelfingen71032 Böblingen75365 Calw72202 Nagold71083 Herrenberg71229 Leonberg");
        // console.log(newText);
        return (        
            <Row>                 
                <Col xs={12} md={2}><b>ID:</b> {props.anzeige.id}</Col>                
                <Col xs={12} md={3}><b>Titel:</b> {props.anzeige.title}</Col>
                <Col xs={12} md={3}><b>Institution:</b> {props.anzeige.institution}</Col>
                <Col xs={12} md={2}><b>Ort:</b> {props.anzeige.ort}</Col>
                <Col xs={12} md={2} className="linkButton">
                <a href={props.anzeige.link} target='_blank' className="anzeigeLink">Link</a> 
                <button  className="finishButton" onClick = {
                        () => {
                            if (window.confirm('Are you sure you wish to finish this document?')) {                        
                                props.onButtonfinish(props.anzeige,props.index);
                                props.onClickalert();
                            }
                        }                    
                    }>fertig</button> 
                </Col> 
                <style jsx>
                {`
                    p, a {          
                    } 
                    .linkButton {                                   
                        flexDirection: 'row',  
                        justifyContent: 'flex-end',   
                    }
                    .anzeigeLink {                    
                    }
                    .finishButton:hover {
                        background-color: green;
                    }
                    .finishButton {    
                        float: right;
                        border: 1px solid blue;
                        border-radius:  10px;
                        background-color: dark-green;             
                    }   
                    @media(max-width: 576px){
                        .finishButton {
                            float: none;
                            margin-right: 30px;
                            margin-left: 20px;
                        }
                    }                 
                `}
                </style>
            </Row>        
        );
    }   

    render() {
        return (
            <div className="anzeigeCard">        
                {this.singleAnzeige(this.props)}
                <DubletteComponent className="dublette" anzeigeID={this.props.anzeige.id} onSendDoubletten = {this.props.onClickAlert}/>
                <style jsx>
                    {`
                        .anzeigeCard {
                            border-radius: 10px;
                            padding: 10px;
                            margin: 5px 0px 5px 0px;
                            border: 1px solid light-green;
                            width: 100%;
                            box-shadow: 2px 2px 2px 2px;
                        }
                    `}        
                </style>                 
            </div>       
        )
    }     
}

export default Anzeige

标签: javascriptreactjsmethodsparent-childnext.js

解决方案


是否存在子组件限制,我只能将方法向下传递 2 个级别左右,以便它仍然有效?

您想将方法作为道具传递多少级别没有限制,

if (this.state.alleAnzeigen.length > 0) {
      anzeigenListe = (
        <AnzeigenComponent 
          anzeigenArray={this.state.alleAnzeigen} 
          onClickAlert={this.onShowAlert}
          onButtonFinish={this.finishDocumentHandler}
        />
      ) 
}

const anzeigenArray = (props) => {
    return props.anzeigenArray.map((anzeige,index) => (      
        <li className="mainList" key={anzeige.id} style={{padding: "10px"}} >
            <Anzeige 
              anzeige={anzeige} 
              key={anzeige.id}
              index={index}  
              onClickalert={props.onClickAlert}
              onButtonfinish={props.onButtonFinish}
            />
        </li>
    ))
}

export default anzeigenArray;

import React, {Component} from 'react';
import DubletteComponent from '../components/DubletteComponent';

import { Button, Alert } from 'reactstrap';
import { Container, Row, Col } from 'reactstrap';


class Anzeige extends Component {     
    constructor(props) {
        super(props);
    }


    singleAnzeige = (props) => {
        // let newText = this.htmlspecialchars_decode("71065 Sindelfingen71032 Böblingen75365 Calw72202 Nagold71083 Herrenberg71229 Leonberg");
        // console.log(newText);
        return (        
            <Row>                 
                <Col xs={12} md={2}><b>ID:</b> {props.anzeige.id}</Col>                
                <Col xs={12} md={3}><b>Titel:</b> {props.anzeige.title}</Col>
                <Col xs={12} md={3}><b>Institution:</b> {props.anzeige.institution}</Col>
                <Col xs={12} md={2}><b>Ort:</b> {props.anzeige.ort}</Col>
                <Col xs={12} md={2} className="linkButton">
                <a href={props.anzeige.link} target='_blank' className="anzeigeLink">Link</a> 

                // I couldn't verify this code, but I guess your "if" implementation may cause some error, so in order to help you investigate easier, I remove the "if" here 
                <button  className="finishButton" onClick = {
                        () => props.onButtonfinish(props.anzeige,props.index);                 
                    }>fertig</button> 
                </Col> 
                <style jsx>
                {`
                    p, a {          
                    } 
                    .linkButton {                                   
                        flexDirection: 'row',  
                        justifyContent: 'flex-end',   
                    }
                    .anzeigeLink {                    
                    }
                    .finishButton:hover {
                        background-color: green;
                    }
                    .finishButton {    
                        float: right;
                        border: 1px solid blue;
                        border-radius:  10px;
                        background-color: dark-green;             
                    }   
                    @media(max-width: 576px){
                        .finishButton {
                            float: none;
                            margin-right: 30px;
                            margin-left: 20px;
                        }
                    }                 
                `}
                </style>
            </Row>        
        );
    }   

    render() {
        return (
            <div className="anzeigeCard">        
                {this.singleAnzeige(this.props)}
                <DubletteComponent className="dublette" anzeigeID={this.props.anzeige.id} onSendDoubletten = {this.props.onClickAlert}/>
                <style jsx>
                    {`
                        .anzeigeCard {
                            border-radius: 10px;
                            padding: 10px;
                            margin: 5px 0px 5px 0px;
                            border: 1px solid light-green;
                            width: 100%;
                            box-shadow: 2px 2px 2px 2px;
                        }
                    `}        
                </style>                 
            </div>       
        )
    }     
}

export default Anzeige


推荐阅读