在React中将数据从子节点传递给父节点

时间:2017-05-13 13:19:51

标签: javascript reactjs

我在React中有3个组件,其中一个组件作为一个容器传递我的子组件以在表单中呈现。提交表单时,我希望获取父组件中的每个子组件,遍历每个组件,创建我的服务器所期望的对象,然后将对象列表发送回服务器。我正在努力访问我的父组件中的onSubmit函数中的子组件。

这是我的父组件

ParentFixturesComponent.js

class ParentFixturesComponent extends Component {

    constructor() {
        super();
        this.state = {
            numChildren: 0,
        };
    }

    onAddMatch() {
        this.setState({
            numChildren: this.state.numChildren + 1
        });
    }

    onSubmit(e) {
        e.preventDefault();
        // loop through the child components
        // create a match object with them
        // var match = {
        //     id: uuid(),
        //     title: uuid(),
        //     start: e.something,
        //     end: e.something,
        // };
        console.log("submit works");
    }

    render() {
        const children = [];
        for (let i = 0; i < this.state.numChildren; i += 1) {
            children.push(<SingleMatchForm key={uuid()}/>)
        }

        return (
            <Fixtures addMatch={this.onAddMatch.bind(this)} save={this.onSubmit.bind(this)} >
                {children}
            </Fixtures>
        );
    }

}

export default ParentFixturesComponent;

保存我的表单的组件,其中我的父级呈现我的所有子组件

ChildFixturesContainer.js

class Fixtures extends Component {


    constructor(props) {
        super(props);
        this.handleChange = this.handleChange.bind(this);
    }

    handleChange(name) {
        this.console.log(this.props);
    }

    render() {
        return (
            <div className="tray tray-center">
                <div className="row">
                    <div className="col-md-8">
                        <div className="panel mb25 mt5">
                            <div className="panel-heading">
                                <span className="panel-title">Fixtures</span>
                            </div>
                            <div className="panel-body p20 pb10">
                                <div id="fixture-parent" onChange={this.handleChange.bind(this)}>
                                    {this.props.children}
                                </div>
                            </div>
                            <div className="section-divider mb40" id="spy1"> </div>
                            <button className="btn btn-primary tm-tag" onClick={this.props.addMatch}>Add Match</button>
                            <button className="btn btn-alert tm-tag" onClick={this.props.save}>Save</button>
                        </div>
                    </div>
                </div>
            </div>
        );
    }

}

export default Fixtures;

最后我的孩子个人形成组件。

SingleMatchComponent.js

class SingleMatchForm extends Component {

    constructor() {
        super();
        this.state = {
            startDate: moment()
        };
    }

    handleChange(date) {
        this.setState({
            startDate: date
        });
    }

    render() {
        return (
            <div className="row">
                <div key={this.props.id} className="form-group">
                    <label className="control-label col-md-2">New Match</label>
                    <div className="col-md-6">
                        <DatePicker
                            selected={this.state.startDate}
                            onChange={this.handleChange.bind(this)}/>
                        <div className="section-divider mb40" id="spy1"> </div>
                    </div>
                </div>
            </div>
        );
    }

}

export default SingleMatchForm;

2 个答案:

答案 0 :(得分:9)

在父级中定义一个函数并将其发送给子级,使用props调用子组件中的父函数。类似的东西:

<强>父

class ParentFixturesComponent extends Component {

    // don't forget to bind the function in parent
    constructor() {
        super();
        this.state = {
            numChildren: 0,
        };
        this.someFunctionHere = this.someFunctionHere.bind(this);
    }

    someFunctionHere(param) {
        // do whatever you need
    }

    render() {
        const children = [];
        for (let i = 0; i < this.state.numChildren; i += 1) {
            children.push(<SingleMatchForm key={uuid()}/>)
        }

        return (
            <Fixtures
                addMatch={this.onAddMatch.bind(this)}
                save={this.onSubmit.bind(this)}
                someFunctionHere={this.someFunctionHere}
            >
                {children}
            </Fixtures>
        );
    }
}

export default ParentFixturesComponent;

儿童

class Fixtures extends Component {

    // constructor and other stuff...

    childFunctionHere() {
        this.props.someFunctionHere(params);            
    }

    render() {
        return (
            <div id="fixture-parent" onChange={this.childFunctionHere}>
        );
    }
}

export default Fixtures;

答案 1 :(得分:3)

基本上,你要问道具和州之间的区别。

有两种类型的数据可以控制组件:propsstateprops由父级设置,并且在组件的整个生命周期内都是固定的。对于要更改的数据,我们必须使用state Docs

这也解决了智能/哑(或逻辑/显示或容器/演示者)组件。

您的父组件应该包含所有状态和更改它的逻辑,然后将所有内容作为props传递给其他组件。您的子组件甚至不应该只有state它们只是处理显示它,当发生某些事情时,它们只是将该回调发送回父组件以执行任何需要完成的操作。

当子组件通过props调用这些处理程序时,它们将在父组件中执行,从而在那里更新状态。然后你可以收集父母的状态并提交。

class TheParent extends component {

  constructor() {
    super();
    this.state = {
      someState: 0,
      someMoreState: 1,
      evenMoreState: 2
    };
    autoBind(this) // <- use autobind so you don't have to list them all out
  }

  updateSomeState() {
        // do something
  }

  updateSomeMoreState() {
        // do something
  }

  updateEvenMoreState() {
        // do something
  }

  onSubmit() {
    // get state and submit
  }

  render () {
    return (
      <Component1 
        someProp={this.state.someState} 
        handler={this.updateSomeState} 
      />
      <Component2 
        someProp={this.state.someMoreState} 
        handler={this.updateSomeMoreState} 
      />          
      <Component2 
        someProp={this.state.evenMoreState} 
        handler={this.updateEvenMoreState} 
      />
    )
  }

}