如何在ReactJS中将数据从子组件传递给它的父组件?

Bir*_*ish 159 reactjs

我正在尝试将数据从子组件发送到它的父组件,如下所示:

const ParentComponent = React.createClass({
    getInitialState() {
        return {
            language: '',
        };
    },
    handleLanguageCode: function(langValue) {
        this.setState({language: langValue});
    },

    render() {
         return (
                <div className="col-sm-9" >
                    <SelectLanguage onSelectLanguage={this.handleLanguage}/> 
                </div>
        );
});
Run Code Online (Sandbox Code Playgroud)

这是子组件:

export const SelectLanguage = React.createClass({
    getInitialState: function(){
        return{
            selectedCode: '',
            selectedLanguage: '',
        };
    },

    handleLangChange: function (e) {
        var lang = this.state.selectedLanguage;
        var code = this.state.selectedCode;
        this.props.onSelectLanguage({selectedLanguage: lang});   
        this.props.onSelectLanguage({selectedCode: code});           
    },

    render() {
        var json = require("json!../languages.json");
        var jsonArray = json.languages;
        return (
            <div >
                <DropdownList ref='dropdown'
                    data={jsonArray} 
                    value={this.state.selectedLanguage}
                    caseSensitive={false} 
                    minLength={3}
                    filter='contains'
                    onChange={this.handleLangChange} />
            </div>            
        );
    }
});
Run Code Online (Sandbox Code Playgroud)

我需要的是在父组件中按用户获取所选值.我收到这个错误:

Uncaught TypeError: this.props.onSelectLanguage is not a function
Run Code Online (Sandbox Code Playgroud)

任何人都可以帮我找到问题吗?

PS子组件正在从json文件创建一个下拉列表,我需要下拉列表来显示彼此相邻的json数组的两个元素(例如:"aaa,english"作为第一选择!)

{  
   "languages":[  
      [  
         "aaa",
         "english"
      ],
      [  
         "aab",
         "swedish"
      ],
}
Run Code Online (Sandbox Code Playgroud)

Shu*_*tri 198

这应该工作.在发送支持时,您将其作为对象发送,而不是将其作为值发送,或者将其用作父组件中的对象.其次,您需要格式化您的json对象以包含名称值对和使用valueFieldtextField属性DropdownList

简答

家长:

<div className="col-sm-9" >
     <SelectLanguage onSelectLanguage={this.handleLanguage}/> 
</div>
Run Code Online (Sandbox Code Playgroud)

儿童:

handleLangChange = () => {
    var lang = this.dropdown.value;
    this.props.onSelectLanguage(lang);            
}
Run Code Online (Sandbox Code Playgroud)

详细:

编辑:

考虑到从V16.0开始不推荐使用React.createClass,最好通过扩展来创建React Component React.Component.使用此语法将数据从子组件传递到父组件将如下所示

class ParentComponent extends React.Component{
    state: { language: '' }

    handleLanguage = (langValue) => {
        this.setState({language: langValue});
    }

    render() {
         return (
                <div className="col-sm-9" >
                    <SelectLanguage onSelectLanguage={this.handleLanguage}/> 
                </div>
        )
     }
}
Run Code Online (Sandbox Code Playgroud)

儿童

var json = require("json!../languages.json");
var jsonArray = json.languages;

export class SelectLanguage extends React.Component {
    state = {
            selectedCode: '',
            selectedLanguage: jsonArray[0],
        }

    handleLangChange = () => {
        var lang = this.dropdown.value;
        this.props.onSelectLanguage(lang);            
    }

    render() {
        return (
            <div >
                <DropdownList ref={(ref) => this.dropdown = ref}
                    data={jsonArray} 
                    valueField='lang' textField='lang'
                    caseSensitive={false} 
                    minLength={3}
                    filter='contains'
                    onChange={this.handleLangChange} />
            </div>            
        );
    }
}
Run Code Online (Sandbox Code Playgroud)

使用createClassOP在他的回答中使用的语法 Parent

const ParentComponent = React.createClass({
    getInitialState() {
        return {
            language: '',
        };
    },
    handleLanguage: function(langValue) {
        this.setState({language: langValue});
    },

    render() {
         return (
                <div className="col-sm-9" >
                    <SelectLanguage onSelectLanguage={this.handleLanguage}/> 
                </div>
        );
});
Run Code Online (Sandbox Code Playgroud)

儿童

var json = require("json!../languages.json");
var jsonArray = json.languages;

export const SelectLanguage = React.createClass({
    getInitialState: function(){
        return{
            selectedCode: '',
            selectedLanguage: jsonArray[0],
        };
    },

    handleLangChange: function () {
        var lang = this.refs.dropdown.value;
        this.props.onSelectLanguage(lang);            
    },

    render() {

        return (
            <div >
                <DropdownList ref='dropdown'
                    data={jsonArray} 
                    valueField='lang' textField='lang'
                    caseSensitive={false} 
                    minLength={3}
                    filter='contains'
                    onChange={this.handleLangChange} />
            </div>            
        );
    }
});
Run Code Online (Sandbox Code Playgroud)

JSON:

{ 
"languages":[ 

    { 
    "code": "aaa", 
    "lang": "english" 
    }, 
    { 
    "code": "aab", 
    "lang": "Swedish" 
    }, 
  ] 
}
Run Code Online (Sandbox Code Playgroud)

  • @Jesse 功能组件也可以有方法。语法会有所不同,但本质保持不变。 (2认同)

小智 93

将数据从子组件传递到父组件

在父组件中:

getData(val){
    // do not forget to bind getData in constructor
    console.log(val);
}
render(){
 return(<Child sendData={this.getData}/>);
}
Run Code Online (Sandbox Code Playgroud)

在子组件中:

demoMethod(){
   this.props.sendData(value);
 }
Run Code Online (Sandbox Code Playgroud)

  • 不要忘记构造函数中的`this.getData = this.getData.bind(this);`,因为如果你想操纵getData中的状态,你可能会得到this.setState不是函数. (11认同)

Sha*_*dam 45

考虑到 React函数组件和使用Hooks越来越流行,我将举一个简单的例子来说明如何将数据从子组件传递到父组件

在父函数组件中,我们将拥有:

import React, { useState } from "react";
Run Code Online (Sandbox Code Playgroud)

然后

const [childData, setChildData] = useState("");
Run Code Online (Sandbox Code Playgroud)

并将 setChildData(在类组件中执行类似于 this.setState 的工作)传递给 Child

return( <ChildComponent passChildData={setChildData} /> )
Run Code Online (Sandbox Code Playgroud)

在子组件中,我们首先获得接收道具

function ChildComponent(props){ return (...) }
Run Code Online (Sandbox Code Playgroud)

然后你可以像使用处理函数一样传递数据

const functionHandler = (data) => {

props.passChildData(data);

}
Run Code Online (Sandbox Code Playgroud)


mam*_*man 18

React v16.8+功能组件中,您可以使用useState()创建一个功能状态,让您更新父状态,然后将其作为道具属性传递给子组件,然后在子组件内部您可以触发父状态功能,以下是一个工作片段:

const { useState , useEffect } = React;

function Timer({ setParentCounter }) {
  const [counter, setCounter] = React.useState(0);

  useEffect(() => {
    let countersystem;
    countersystem = setTimeout(() => setCounter(counter + 1), 1000);

    return () => {
      clearTimeout(countersystem);
    };
  }, [counter]);

  return (
    <div className="App">
      <button
        onClick={() => {
          setParentCounter(counter);
        }}
      >
        Set parent counter value
      </button>
      <hr />
      <div>Child Counter: {counter}</div>
    </div>
  );
}

function App() {
  const [parentCounter, setParentCounter] = useState(0);

  return (
    <div className="App">
      Parent Counter: {parentCounter}
      <hr />
      <Timer setParentCounter={setParentCounter} />
    </div>
  );
}

ReactDOM.render(<App />, document.getElementById('react-root'));
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="react-root"></div>
Run Code Online (Sandbox Code Playgroud)


小智 11

您可以使用在 ParentComponent 中创建状态useState并将setIsParentData函数作为 prop传递给 ChildComponent。

在 ChildComponent 中,通过 prop 使用接收到的函数更新数据,将数据发送回 ParentComponent。

我使用这种技术特别是当我在 ParentComponent 中的代码变得太长时,因此我将从 ParentComponent 创建子组件。通常,它只会向下 1 个级别,并且使用 useContext 或 redux 似乎过分在组件之间共享状态。

ParentComponent.js

import React, { useState } from 'react';
import ChildComponent from './ChildComponent';

export function ParentComponent(){
  const [isParentData, setIsParentData] = useState(True);

  return (
    <p>is this a parent data?: {isParentData}</p>
    <ChildComponent toChild={isParentData} sendToParent={setIsParentData} />
  );
}
Run Code Online (Sandbox Code Playgroud)

ChildComponent.js

import React from 'react';

export function ChildComponent(props){

  return (
    <button onClick={() => {props.sendToParent(False)}}>Update</button>
    <p>The state of isParentData is {props.toChild}</p>
  );
};
Run Code Online (Sandbox Code Playgroud)


Man*_*ana 10

从子组件到父组件如下

父组件

class Parent extends React.Component {
   state = { message: "parent message" }
   callbackFunction = (childData) => {
       this.setState({message: childData})
   },
   render() {
        return (
            <div>
                 <Child parentCallback = {this.callbackFunction}/>
                 <p> {this.state.message} </p>
            </div>
        );
   }
}
Run Code Online (Sandbox Code Playgroud)

子组件

class Child extends React.Component{
    sendBackData = () => {
         this.props.parentCallback("child message");
    },
    render() { 
       <button onClick={sendBackData}>click me to send back</button>
    }
};
Run Code Online (Sandbox Code Playgroud)

我希望这项工作


小智 10

最近发现了一种很棒且简单的方法来通过输入来做到这一点。

本质上,我只是 useState ,然后将 onChange 设置为子组件的支柱,它以“值”作为参数并将其放入 useState“setVal”繁荣中,我每次都会得到状态更改子->父

const Parent = () => {
  const [val, setVal] = useState("initial value")
  return(
    <>
    <Child onChange={(value)=> setVal(value)}/>
    <div>{val}</div>
    </>
  )
};

export default Parent;

const Child = (props) => {
  return(
  <button onClick={() => props.onChange("your value here") }>
  )
}
Run Code Online (Sandbox Code Playgroud)


Rah*_*rma 8

在这里我试图用最简单的方式解释:我正在从子组件更新父组件计数器。

父组件(PropsApp.jsx)

import React, { useState } from 'react'
import Child from './Child'

export default function PropsApp(){
   const [counter, setCounter] = useState(0)

   const updateMyCounter = () => {
       setCounter(counter + 1)
   }

   return(
    <>  
        <hr></hr>
        <h1>This is Parent</h1>
        <h2>{counter}</h2>
        <Child updateParent={updateMyCounter} />
    </>
   )
}
Run Code Online (Sandbox Code Playgroud)

子组件(Child.jsx)

export default function Child(props){

return(
    <>  
        <hr></hr>
        <h1>This is Child</h1>
        <button
            onClick={props.updateParent}
        >
            Update Parent Component
        </button>
    </>
   )
}
Run Code Online (Sandbox Code Playgroud)

单击“更新父组件”即可看到神奇的效果 在此输入图像描述


MrD*_*uDu 7

我找到了在需要时如何从父项中的子组件获取数据的方法.

家长:

class ParentComponent extends Component{
  onSubmit(data) {
    let mapPoint = this.getMapPoint();
  }

  render(){
    return (
      <form onSubmit={this.onSubmit.bind(this)}>
        <ChildComponent getCurrentPoint={getMapPoint => {this.getMapPoint = getMapPoint}} />
        <input type="submit" value="Submit" />
      </form>
    )
  }
}
Run Code Online (Sandbox Code Playgroud)

儿童:

class ChildComponent extends Component{
  constructor(props){
    super(props);

    if (props.getCurrentPoint){
      props.getCurrentPoint(this.getMapPoint.bind(this));
    }
  }

  getMapPoint(){
    return this.Point;
  }
}
Run Code Online (Sandbox Code Playgroud)

此示例显示如何将函数从子组件传递到父组件并使用此函数从子组件获取数据.


Ben*_*rts 5

在 React 中将数据从子组件传递到父组件:

  1. 将函数从接收值的父级传递给子级。
  2. 当子组件中的值发生更改时,使用更新后的值调用该函数。

例如

const Parent = () => {

  const handleChange = values => {
     alert(JSON.stringify(values) );
     //do something with the values  
  }

  return (
    <Child handleChange={handleChange} />
  );
}

const Child = ({handleChange}) => {
    return (
        <button onClick={() => handleChange('values you wish to pass') }></button>
    );
}
Run Code Online (Sandbox Code Playgroud)

注意:从 React 16 开始,我建议在几乎所有情况下都使用函数组件。