ReactJS调用父方法


140

我正在React React中迈出第一步,并试图理解父母与孩子之间的交流。我正在制作表格,所以我有用于样式字段的组件。而且我还有包含字段并对其进行检查的父组件。例:

var LoginField = React.createClass({
    render: function() {
        return (
            <MyField icon="user_icon" placeholder="Nickname" />
        );
    },
    check: function () {
        console.log ("aakmslkanslkc");
    }
})

var MyField = React.createClass({
    render: function() {
...
    },
    handleChange: function(event) {
//call parent!
    }
})

有没有办法做到这一点。我的逻辑在reactjs“ world”上好吗?谢谢你的时间。

Answers:


154

为此,您将回调作为属性从父级传递给子级。

例如:

var Parent = React.createClass({

    getInitialState: function() {
        return {
            value: 'foo'
        }
    },

    changeHandler: function(value) {
        this.setState({
            value: value
        });
    },

    render: function() {
        return (
            <div>
                <Child value={this.state.value} onChange={this.changeHandler} />
                <span>{this.state.value}</span>
            </div>
        );
    }
});

var Child = React.createClass({
    propTypes: {
        value:      React.PropTypes.string,
        onChange:   React.PropTypes.func
    },
    getDefaultProps: function() {
        return {
            value: ''
        };
    },
    changeHandler: function(e) {
        if (typeof this.props.onChange === 'function') {
            this.props.onChange(e.target.value);
        }
    },
    render: function() {
        return (
            <input type="text" value={this.props.value} onChange={this.changeHandler} />
        );
    }
});

在上面的示例中,Parent调用Child具有value和属性的调用onChange。的Child回报结合一个onChange处理程序,以一个标准的<input />元件,并传递值到Parent如果它定义的回调函数。

结果,调用ParentchangeHandler方法时,第一个参数是的<input />字段中的字符串值Child。结果是Parent可以使用该值更新的状态,从而在<span />您在Child的输入字段中键入新值时,父元素将更新为新值。


15
我认为您需要在将父函数传递给孩子之前先对其进行绑定:<Child value={this.state.value} onChange={this.changeHandler.bind(this)} />
o01 2015年

19
@ o01不,您不会,因为我正在使用React.createClass哪个自动绑定所有组件方法。如果我使用的是React es6类,那么您需要对其进行绑定(除非您在构造函数中进行自动绑定,这是当今很多人为解决这个问题所做的工作)
Mike Driver

1
@MikeDriver我明白了。不知道这仅限于使用ECMAScript 6类的情况(我是)。还不知道React团队建议在构造函数中使用自动绑定。
o01年5

1
我不知道他们是否推荐它,但这似乎很常见。与将绑定放入渲染线程中相比,这对我来说更有意义,原因是它会.bind返回一个新函数,因此,基本上,您每次运行render时都会创建一个新函数。这可能很好,但是如果绑定到构造函数中,则在实例化时每个组件方法仅执行一次此操作,而不是每个渲染一次。这是挑剔的...但是我想从技术上来说更好!
Mike Driver

1
@ DavidLy-Gagnon在示例中很好,可能未定义,因为我没有在propType上附加isRequired。但是是的,您可以执行此操作,也可以只检查它是否已定义。
Mike Driver

52

您可以使用任何父方法。为此,您应该像任何简单值一样,将此方法从父级发送给您的孩子。您可以一次使用父级的许多方法。例如:

var Parent = React.createClass({
    someMethod: function(value) {
        console.log("value from child", value)
    },
    someMethod2: function(value) {
        console.log("second method used", value)
    },
    render: function() {
      return (<Child someMethod={this.someMethod} someMethod2={this.someMethod2} />);
    }
});

并像这样将其用于Child(用于任何操作或任何子方法):

var Child = React.createClass({
    getInitialState: function() {
      return {
        value: 'bar'
      }
    },
    render: function() {
      return (<input type="text" value={this.state.value} onClick={this.props.someMethod} onChange={this.props.someMethod2} />);
    }
});

1
辉煌的答案。不知道您可以像这样将方法传递为道具,我一直在使用refs来实现!
保罗·雷德蒙德

1
我得到了要由孩子调用的回调,但是this.props回调变成了undefined
khateeb

您应该将此回调从父级发送到子级(尝试将此回调与绑定this
Vitaliy Andrusishyn

嗨Valentin Petkov。欢迎!
Vitaliy Andrusishyn

39

2019更新带有React 16+和ES6

由于React.createClass从react版本16 起已弃用此功能,而新的Javascript ES6将为您带来更多好处。

父母

import React, {Component} from 'react';
import Child from './Child';
  
export default class Parent extends Component {

  es6Function = (value) => {
    console.log(value)
  }

  simplifiedFunction (value) {
    console.log(value)
  }

  render () {
  return (
    <div>
    <Child
          es6Function = {this.es6Function}
          simplifiedFunction = {this.simplifiedFunction} 
        />
    </div>
    )
  }

}

儿童

import React, {Component} from 'react';

export default class Child extends Component {

  render () {
  return (
    <div>
    <h1 onClick= { () =>
            this.props.simplifiedFunction(<SomethingThatYouWantToPassIn>)
          }
        > Something</h1>
    </div>
    )
  }
}

ES6常量简化了无状态子级

import React from 'react';

const Child = () => {
  return (
    <div>
    <h1 onClick= { () =>
        this.props.es6Function(<SomethingThatYouWantToPassIn>)
      }
      > Something</h1>
    </div>
  )

}
export default Child;

在ES6 JS中看到4个空格而不是2个空格让我很难过:'(
Bataleon

3

将方法从Parent组件向下作为传递prop给您的Child组件。即:

export default class Parent extends Component {
  state = {
    word: ''
  }

  handleCall = () => {
    this.setState({ word: 'bar' })
  }

  render() {
    const { word } = this.state
    return <Child handler={this.handleCall} word={word} />
  }
}

const Child = ({ handler, word }) => (
<span onClick={handler}>Foo{word}</span>
)

2

使用功能|| 无状态组件

父组件

 import React from "react";
 import ChildComponent from "./childComponent";

 export default function Parent(){

 const handleParentFun = (value) =>{
   console.log("Call to Parent Component!",value);
 }
 return (<>
           This is Parent Component
           <ChildComponent 
             handleParentFun={(value)=>{
               console.log("your value -->",value);
               handleParentFun(value);
             }}
           />
        </>);
}

子组件

import React from "react";


export default function ChildComponent(props){
  return(
         <> This is Child Component 
          <button onClick={props.handleParentFun("YoureValue")}>
            Call to Parent Component Function
          </button>
         </>
        );
}

1
要为您的答案增加价值,请考虑对这段代码的作用进行简短说明。
Cray

当您单击子组件中的按钮,然后通过道具调用父组件功能时。
Omkesh Sajjanwar

1
如果函数具有参数怎么办?如何将参数传递给父级?
alex351

是!@ alex351我们可以处理这种情况。在子组件中-> onClick = {props.handleParentFun(“ YoureValue”)}在父组件中-> handleParentFun = {((value)=> {{console.log(); handleChildFun(value); }}
Omkesh Sajjanwar

0

反应16+

子组件

import React from 'react'

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

    render()
    {
        return <div>
            <button onClick={()=>this.props.greetChild('child')}>Call parent Component</button>
        </div>
    }
}

export default ChildComponent;

父组件

import React from "react";
import ChildComponent from "./childComponent";

class MasterComponent extends React.Component
{
    constructor(props)
    {
        super(props);
        this.state={
            master:'master',
            message:''
        }
        this.greetHandler=this.greetHandler.bind(this);
    }

    greetHandler(childName){
        if(typeof(childName)=='object')
        {
            this.setState({            
                message:`this is ${this.state.master}`
            });
        }
        else
        {
            this.setState({            
                message:`this is ${childName}`
            });
        }

    }

    render()
    {
        return <div>
           <p> {this.state.message}</p>
            <button onClick={this.greetHandler}>Click Me</button>
            <ChildComponent greetChild={this.greetHandler}></ChildComponent>
        </div>
    }
}
export default  MasterComponent;
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.