简体   繁体   English

如何在 Reactjs 中从外部调用主组件内部的方法

[英]How to call method inside main Component from outside in Reactjs

I need to call cancelMethod with params from Button onClick inside popover .我需要使用 popover 中 Button popover的参数调用cancelMethod However I could not access this method.但是我无法访问此方法。 Can you explain is it possible to access.你能解释一下是否可以访问。 If yes how can I do it?如果是,我该怎么做?

const popover = (
  <Popover id="popover-basic">
    <Popover.Title as="h3">Cancel reservation</Popover.Title>
    <Popover.Content>
     for <strong>canceling</strong> course. Click here:
     <Button onClick={cancelMethod()} variant='danger'>Cancel</Button>
    </Popover.Content>
  </Popover>
);

const Event = ({event}) => (
  <OverlayTrigger trigger="click" placement="top" overlay={popover}>
    <Button 
     style={{background:"transparent", border:"none"}}
    >{event.title} <br/> Lecture Room:{event.room}<br/> Teacher: {event.instructor}</Button>
  </OverlayTrigger>
);


export default class NewCalendarView extends Component {

  cancelMethod(id){
    alert("Hello"+id);
  }

  componentDidMount() {
    API.getLectures().then((res)=>{
      console.log(res)
       const cal=res.map((lec)=>{
         let lecture= {
           instructor: lec.teacherName,
          room: lec.room,
          title: lec.subject,
          startDate : moment(lec.date+"T"+lec.hour).toDate(),
          endDate:  moment(lec.date+"T"+lec.hour+"-02:00").toDate()
          }   
          return lecture;
      })
          this.setState({events:cal,loading:null,serverErr:null})
    }).catch((err)=>{
        this.setState({serverErr:true,loading:null})
    })
}
  constructor(props) {
    super(props);

    this.state = {
       events: []
    }
  }

  render() {
    return (
      <div style={{
        flex: 1
      }}>
        {console.log(this.state.events)}

        <Calendar
          localizer={localizer}
          events={this.state.events}
          startAccessor='startDate'
          endAccessor='endDate'
          defaultView='week'
          views={['month', 'week', 'day']}
          culture='en'
          components={{
            event: Event
          }}

          />
      </div>
    );
  }
}

You can define the functions Popover and Event within the class and the call the function with this keyword.您可以在class 中定义函数Popover 和Event,并使用此关键字调用function。

export default class NewCalendarView extends Component {
  cancelMethod(id){
    alert("Hello"+id);
  }

  componentDidMount() {
    API.getLectures().then((res)=>{
      console.log(res)
       const cal=res.map((lec)=>{
         let lecture= {
           instructor: lec.teacherName,
          room: lec.room,
          title: lec.subject,
          startDate : moment(lec.date+"T"+lec.hour).toDate(),
          endDate:  moment(lec.date+"T"+lec.hour+"-02:00").toDate()
          }   
          return lecture;
      })
          this.setState({events:cal,loading:null,serverErr:null})
    }).catch((err)=>{
        this.setState({serverErr:true,loading:null})
    })
}
  constructor(props) {
    super(props);

    this.state = {
       events: []
    }
  }

Popover = (
  <Popover id="popover-basic">
    <Popover.Title as="h3">Cancel reservation</Popover.Title>
    <Popover.Content>
     for <strong>canceling</strong> course. Click here:
     <Button onClick={cancelMethod()} variant='danger'>Cancel</Button>
    </Popover.Content>
  </Popover>
);

Event = ({event}) => (
  <OverlayTrigger trigger="click" placement="top" overlay={this.popover}>           // added the this keyword
    <Button 
     style={{background:"transparent", border:"none"}}
    >{event.title} <br/> Lecture Room:{event.room}<br/> Teacher: {event.instructor}</Button>
  </OverlayTrigger>
);

  render() {
    return (
      <div style={{
        flex: 1
      }}>
        {console.log(this.state.events)}

        <Calendar
          localizer={localizer}
          events={this.state.events}
          startAccessor='startDate'
          endAccessor='endDate'
          defaultView='week'
          views={['month', 'week', 'day']}
          min={new Date(2020, 1, 0, 7, 0, 0)} 
          max={new Date(2022, 1, 0, 21, 0, 0)}
          culture='en'
          components={{
            event: this.Event           // added the this keyword
          }}

          />
      </div>
    );
  }
}

One way would be to pass it as prop to popover (which I renamed to PopoverInstance as Popover was already taken).一种方法是将它作为 prop 传递给 popover(我将其重命名为 PopoverInstance,因为 Popover 已经被采用)。 This unfortunately has a side effect of having to drill the prop two levels down (instead of direct one level down).不幸的是,这有一个副作用,那就是必须将道具向下钻两层(而不是直接向下一层)。 An alternative approach would be to introduce outside state (like Context or Redux) that manages state and methods.另一种方法是引入外部 state(如 Context 或 Redux)来管理 state 和方法。 It would certainly help with prop drilling.这肯定有助于螺旋桨钻井。

If cancelMethod is only used in this popover, you can consider moving it there as well.如果cancelMethod只在这个 popover 中使用,你也可以考虑将它移到那里。

Also I am unsure how Calendar works, so take that into consideration when you look at the example I've set below.此外,我不确定 Calendar 是如何工作的,所以当您查看我在下面设置的示例时,请考虑到这一点。

const PropoverInstance = ({cancelMethod}) => (
  <Popover id="popover-basic">
    <Popover.Title as="h3">Cancel reservation</Popover.Title>
    <Popover.Content>
     for <strong>canceling</strong> course. Click here:
     <Button onClick={cancelMethod()} variant='danger'>Cancel</Button>
    </Popover.Content>
  </Popover>
);

const Event = ({event, cancelMethod}) => (
  <OverlayTrigger trigger="click" placement="top" overlay={<PopoverInstance cancelMethod={cancelMethod} />}>
    <Button 
     style={{background:"transparent", border:"none"}}
    >{event.title} <br/> Lecture Room:{event.room}<br/> Teacher: {event.instructor}</Button>
  </OverlayTrigger>
);


export default class NewCalendarView extends Component {

  cancelMethod(id){
    alert("Hello"+id);
  }

  componentDidMount() {
    API.getLectures().then((res)=>{
      console.log(res)
       const cal=res.map((lec)=>{
         let lecture= {
           instructor: lec.teacherName,
          room: lec.room,
          title: lec.subject,
          startDate : moment(lec.date+"T"+lec.hour).toDate(),
          endDate:  moment(lec.date+"T"+lec.hour+"-02:00").toDate()
          }   
          return lecture;
      })
          this.setState({events:cal,loading:null,serverErr:null})
    }).catch((err)=>{
        this.setState({serverErr:true,loading:null})
    })
}
  constructor(props) {
    super(props);

    this.state = {
       events: []
    }
  }

  render() {
    return (
      <div style={{
        flex: 1
      }}>
        {console.log(this.state.events)}

        <Calendar
          localizer={localizer}
          events={this.state.events}
          startAccessor='startDate'
          endAccessor='endDate'
          defaultView='week'
          views={['month', 'week', 'day']}
          culture='en'
          components={{
            event: <Event event={???} cancelMethod={cancelMethod} />
          }}

          />
      </div>
    );
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM