Nick Pocock Nick Pocock - 4 years ago 121
React JSX Question

Getting data from child select box in parent using ReactJS

I have a child component with a select form element, this queries my API and makes a select box out of the data. I then try to pass the option back that's been selected via an OnChange function to my parent component so I can then send my data back to the server. I keep getting an error saying state is not defined, I am new to react and can't see where I am going wrong.

Here is my parent component

var ReactDom = require('react-dom');
const uuid = require('uuid/v1');
import {postDataTest} from "../actions/postData";
import TeamSelectBox from "./TeamSelectBox";
import React, {Component, PropTypes} from "react";

class PlayerForm extends Component {

constructor(props) {
super(props);
this.state = {
teamId: ''
};
this.handleChange = this.handleChange.bind(this);
}


fieldValues = {
name: null,
teamName: null,
bio: null
}

handleChange(dataFromChild) {
console.log(dataFromChild);
}

nextStep(e) {
e.preventDefault();
// Get values via this.refs
var player = {
id: uuid(),
name: ReactDom.findDOMNode(this.refs.name).value,
teamName: ReactDom.findDOMNode(this.refs.teamName).value,
bio: ReactDom.findDOMNode(this.refs.bio).value,
teamId: ReactDom.findDOMNode(this.refs.teamId).value
};

postDataTest(player);
}

render() {
return (
<div className="row">
<div className="col-md-6">
<div className="panel">
<div className="panel-heading">
<h1>Add Player</h1>
</div>
<div className="panel-body">
<form className="form-horizontal">
<div className="form-group">
<label className="control-label">Name</label>
<input type="text" className="form-control" ref="name" defaultValue={this.fieldValues.name}/>
</div>
<div className="form-group">
<label className="control-label">Team Name</label>
<input type="text" className="form-control" ref="teamName" defaultValue={this.fieldValues.teamName}/>
</div>
<TeamSelectBox state={this.state.teamId} onChange={this.handleChange}/>
<div className="form-group">
<label className="control-label">Bio</label>
<input type="textarea" className="form-control" ref="bio" defaultValue={this.fieldValues.bio}/>
</div>
<div className="bs-component">
<button className="btn btn-md btn-default btn-block" onClick={this.nextStep}>Save &amp; Continue</button>
</div>
</form>
</div>
</div>
</div>
</div>
)
}
}

module.exports = PlayerForm;


And here is my child form select box

import React, {Component} from "react";
import axios from "axios";
import {postDataTest} from '../actions/postData';

class TeamSelectBox extends Component {

constructor(props) {
super(props);
this.state = {
teams: []
};
}


componentDidMount() {
axios.get("/api/teams")
.then(response => {
const teams = response.data;
this.setState({teams});
console.log(teams);
});
}

render() {
return (
<div className="form-group">
<label for="inputSelect" className="control-label">Select Team</label>
<div className="bs-component">
<select value={this.probs.state.teamId} onChange={this.probs.onChange} className="form-control">
<option value=""></option>
{this.state.teams.map(singleTeam =>
<option value={singleTeam.id}>{singleTeam.team.name}</option>
)}
</select>
</div>
</div>
);
}

}

export default TeamSelectBox;

Answer Source

Your approach seems OK, but you had a typo in your child Component:

{this.probs.onChange}

change it to {this.props.onChange} and try again!

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download