Javascript 如何从另一个组件中的组件正确调用函数

Javascript 如何从另一个组件中的组件正确调用函数,javascript,reactjs,gatsby,Javascript,Reactjs,Gatsby,我看到了一些类似的问题,但关于父/子元素,我有这样的节点树: IndexPage -> Modals -> ClientDetails(it's modal component) -> Header 我想在Header中调用ClientDetails.OpenModel,尝试了许多方法,比如在indexPage中为ClientDetails创建引用,然后像prop一样将indexPage传递到Header,但工作起来很奇怪,我看到了props.indexP

我看到了一些类似的问题,但关于父/子元素,我有这样的节点树:

IndexPage -> Modals -> ClientDetails(it's modal component)
          -> Header
我想在Header中调用ClientDetails.OpenModel,尝试了许多方法,比如在indexPage中为ClientDetails创建引用,然后像prop一样将indexPage传递到Header,但工作起来很奇怪,我看到了props.indexPage的引用,但当尝试直接访问引用时,它处于查找不足状态


我会尝试这样做:

class IndexPage extends React.Component {
  constructor(props) {
    super(props);

    this.state = {modalsRef: null};
  }

  render() {
    return (
      <Layout>
        <SEO/>
        <Header modalsRef={this.state.modalsRef}/>
        <Story/>
        <Products/>
        <Clients/>
        <Reviews/>
        <Partners/>
        <Footer/>
        <Modals ref={r => !this.state.modalsRef && this.setState({modalsRef:r})} />
      </Layout>
    )
  }
}
class IndexPage扩展了React.Component{
建造师(道具){
超级(道具);
this.state={modalsRef:null};
}
render(){
返回(
!this.state.modalsRef&&this.setState({modalsRef:r})}/>
)
}
}

但请注意:该属性很可能在Header的构造函数中不起作用。不过,当您执行Button.onClick回调等操作时,它应该可以工作。

我会尝试这样做:

class IndexPage extends React.Component {
  constructor(props) {
    super(props);

    this.state = {modalsRef: null};
  }

  render() {
    return (
      <Layout>
        <SEO/>
        <Header modalsRef={this.state.modalsRef}/>
        <Story/>
        <Products/>
        <Clients/>
        <Reviews/>
        <Partners/>
        <Footer/>
        <Modals ref={r => !this.state.modalsRef && this.setState({modalsRef:r})} />
      </Layout>
    )
  }
}
class IndexPage扩展了React.Component{
建造师(道具){
超级(道具);
this.state={modalsRef:null};
}
render(){
返回(
!this.state.modalsRef&&this.setState({modalsRef:r})}/>
)
}
}

但请注意:该属性很可能在Header的构造函数中不起作用。但在您执行Button.onClick回调等操作时,它应该可以工作。

这里有一个小提琴,用于从父函数调用子函数

类模态扩展React.Component{
建造师(道具){
超级(道具);
此。状态={
showModal:错误
}
this.toggleModal=this.toggleModal.bind(this)
}
toggleModal(){this.setState({showModal:!this.state.showModal}}
render(){
const{showmodel}=this.state;
返回(
{showmodel&&
显示模态
}
)
}
}
类TodoApp扩展了React.Component{
建造师(道具){
超级(道具)
this.modalRef=React.createRef()
this.handleClick=this.handleClick.bind(this);
}
handleClick(){
this.modalRef.current.toggleModal();
}
render(){
返回(
点击
)
}
}
ReactDOM.render(,document.querySelector(“#app”))

这里有一个小提琴,用于从父函数调用子函数

类模态扩展React.Component{
建造师(道具){
超级(道具);
此。状态={
showModal:错误
}
this.toggleModal=this.toggleModal.bind(this)
}
toggleModal(){this.setState({showModal:!this.state.showModal}}
render(){
const{showmodel}=this.state;
返回(
{showmodel&&
显示模态
}
)
}
}
类TodoApp扩展了React.Component{
建造师(道具){
超级(道具)
this.modalRef=React.createRef()
this.handleClick=this.handleClick.bind(this);
}
handleClick(){
this.modalRef.current.toggleModal();
}
render(){
返回(
点击
)
}
}
ReactDOM.render(,document.querySelector(“#app”))

我认为您可以使用react.js解决您的问题。 您想要控制Header组件中的Modals组件。因此,您尝试引用Header组件中的Modals组件切换函数来解决此问题。 我认为这是一个很好的解决办法。 但在我看来,在对等组件中共享状态也是另一种解决方案。 因此,您可以使用react.js上下文在其父组件中的两个对等组件之间共享状态。我认为这样做是遵循react声明式编程


我认为您可以使用react.js解决您的问题。 您想要控制Header组件中的Modals组件。因此,您尝试引用Header组件中的Modals组件切换函数来解决此问题。 我认为这是一个很好的解决办法。 但在我看来,在对等组件中共享状态也是另一种解决方案。 因此,您可以使用react.js上下文在其父组件中的两个对等组件之间共享状态。我认为这样做是遵循react声明式编程


你说你试过裁判。您是否尝试过引用当前版本?例如,回答:是的,我在Modals中引用了ClientDetails,在IndexPage中引用了Modals,然后将IndexPage作为道具传递,问题是在标题中,我无法通过indexPage获得引用,我看不到代码的结构,所以我不确定您在标题中做了什么,以及从何处获得引用。看附的两张图片,indexPage有modals(它是ref),当我记录indexPage.modals时,它是null。您说您尝试了引用。您是否尝试过引用当前版本?例如,回答:是的,我在Modals中引用了ClientDetails,在IndexPage中引用了Modals,然后将IndexPage作为道具传递,问题是在标题中,我无法通过indexPage获得引用,我看不到代码的结构,所以我不确定您在标题中做了什么,以及从何处获得引用。看附的两张图片,indexPage有modals(它是ref),当我记录indexPage.modals时,它是null
class Header extends React.Component {
  constructor(props) {
    super(props);
    this.state = { isActive: false, isSticky: false };
    this.toggle = this.toggle.bind(this);


    this.indexPage = props.indexPage
    console.log(this.indexPage)
    console.log(this.indexPage.modals)
  }
}
class IndexPage extends React.Component {
  constructor(props) {
    super(props);

    this.state = {modalsRef: null};
  }

  render() {
    return (
      <Layout>
        <SEO/>
        <Header modalsRef={this.state.modalsRef}/>
        <Story/>
        <Products/>
        <Clients/>
        <Reviews/>
        <Partners/>
        <Footer/>
        <Modals ref={r => !this.state.modalsRef && this.setState({modalsRef:r})} />
      </Layout>
    )
  }
}
class Modal extends React.Component {
 constructor(props) {
  super(props);
  this.state= {
   showModal: false
  }
  this.toggleModal = this.toggleModal.bind(this)
 }
 toggleModal() {this.setState({showModal: !this.state.showModal})}

render() {
 const { showModal } = this.state;
 return(
  <div className="modal">
   {showModal && 
    <div>
     Showing modal
    </div>
   }
  </div>
 )
 }
}

class TodoApp extends React.Component {
 constructor(props) {
   super(props)
   this.modalRef = React.createRef()
   this.handleClick = this.handleClick.bind(this);
 }

 handleClick() {
  this.modalRef.current.toggleModal();
 }

 render() {
   return (
     <div className="parent">
       <Modal ref={this.modalRef} />
       <button onClick={this.handleClick}>Click</button>
     </div>
   )
 }
}

ReactDOM.render(<TodoApp />, document.querySelector("#app"))