I have a form with a select box that gets data from the server and post it to the same server. I'm using select box from ant design.
But that part that handles changes handleChange() is not working and give me this error :
Cannot read property 'value' of undefined
This is my code:
let optionData = [];
class ContentCountries extends React.Component {
constructor(props){
super(props);
this.state = {
value: 'Select',
jsonData: 0
};
}
handleChange(event) {
this.setState({value: event.target.value});
}
handleSubmit(event) {
event.preventDefault();
var data = {
name: this.state.value
}
console.log(data);
/*$.ajax({
type: 'POST',
url: 'https://google.com',
data: data
})*/
}
componentDidMount(){
//ajax request
/*$.ajax({
type: 'GET',
url: 'https://google.com',
succes: function(data){
optionData = data;
}
})*/
//static example
optionData.push('Bangalore');
optionData.push('Pune');
this.setState({jsonData: 1});//change the status so the select tag will get the new values(render will happen)
}
render() {
var optionsTag = <Option value="">Select City</Option>
if(optionData.length){
optionsTag = optionData.map((data,index) => {
return <Option value={data} key={index}>{data}</Option>
})
}
return (
<form onSubmit={false}>
<label>
Please select city:
<Select value={this.state.value} onChange={this.handleChange.bind(this)}>
{ optionsTag}
</Select>
</label>
<input type="button" onClick={this.handleSubmit.bind(this)} value="Submit" />
</form>
)
}
}
EDITED: Sorry, as you said, it is Ant Design. However, it is almost the same with your handleChange function.
Because it takes the value as the argument, not the event. So that there is no target property inside passed argument.
handleChange(val) {
this.setState({value: val});
}
Related
I am new to react and to get to grips with it, I'm converting existing project from jQuery to React.
I have six select boxes that update sequentially depending on the selection of the previous select box e.g. select option FOO from select box A and select box B must update with items corresponding to FOO.
I'll list some of references at the bottom
What I have so far:
I've got onchange events using fetch to call my api and get the data I want to use to populate the next select box and this is where I'm hitting a wall.
I've written two components MapControls and SelectBox. MapControls has an array of objects in its state that are used to generate a collection of SelectBox instances
Here's the MapControls component:
class MapControls extends React.Component {
state = {
selectBoxes: [
{
id: 'WorkSource',
name: 'WorkSource',
title:'Work Source',
containerId: 'WorkSourceContainer',
className: 'WorkSource',
childControllerMethod: 'GetBusinessTypeDropdown',
items: [{value:0, text:'Select'}, { value: '1', text: 'Routed' }],
child: 'BusinessType'
},
{
id: 'BusinessType',
name: 'BusinessType',
title: 'Business Type',
containerId: 'BusinessTypeContainer',
className: 'BusinessType',
childControllerMethod: 'GetWorkTypeDropdown',
items: [{ value: 0, text: 'Select' }],
child: 'WorkType'
},
//... more items ...
]
}
render() {
return this.state.selectBoxes.map(selectBox =>
<div key={selectBox.id} className='col-xs-2'>
<div id={selectBox.containerId}>
<SelectBox id={selectBox.id} name={selectBox.name} selectBox={selectBox} onChange={this.handleChange} />
</div>
</div>
);
}
};
and here's the SelectBox component. It's in the handleChange event where I want to be able to update the items in another SelectBox instance based on the ref. See the inline comments that describe my stumbling blocks
class SelectBox extends React.Component{
constructor(props) {
super(props);
this.state = { items: this.props.selectBox.items };
this.handleChange = this.handleChange.bind(this);
}
handleChange(event) {
const selectedValue = event.target.value;
const url = "/Home/" + event.target.dataset.childControllerMethod;
const data = JSON.stringify({ selectedValue: selectedValue });
fetch(url, {
method: 'post',
headers: {
'Accept': 'application/json, text/plain, */*',
'Content-Type': 'application/json'
},
body: data
}).then(response => {
if (response.status >= 400) {
console.log("Bad response from server");
}
return response.json();
}).then(data => {
// This updates the selectbox that was changed, which is not what I want
// this.setState({ items: data})
// This is what I was hoping would work, but I've discovered that BusinessType is a DOM element here, so setState is not valid
// this.refs.BusinessType.setState({ items: data });
// I hardcorded the 'BusinessType' as a ref just for testing because I know it's valid, but I want this to be dynamic
// findDOMNode seems to be somewhat of an anti-pattern, so I'd rather not do this. Not that the below code works because sibling is not a React object
// let sibling = ReactDOM.findDOMNode(this.refs.BusinessType);
// sibling.setState({ items: data });
});
}
render()
{
const optionItems = this.state.items.map((item, index) =>
<option key={index} value={item.value} >{item.text}</option>
);
return <div>
<label htmlFor={this.props.selectBox.id} >{this.props.selectBox.title}</label>
<select onChange={this.handleChange} id={this.props.selectBox.id} ref={this.props.selectBox.child} /*data-child={this.props.selectBox.child}*/ data-child-controller-method={this.props.selectBox.childControllerMethod}>
{optionItems}
</select>
</div>
}
};
ReactDOM.render(<MapControls />,
document.getElementById('mapControls')
);
Places I've looked:
http://jamesknelson.com/react-js-by-example-interacting-with-the-dom/
https://reactjs.org/docs/react-dom.html#finddomnode
https://reactjs.org/docs/refs-and-the-dom.html
http://www.mattmorgante.com/technology/dropdown-with-react
https://davidwalsh.name/get-react-component-element
https://www.carlrippon.com/react-drop-down-data-binding/
What you seem to be wanting is similar to Angular's two way binding using #input #output.
What you can do is the following:
class MapControls extends React.Component{
constructor(props){
super(props); // needed
this.state = {...} // Your declared state above
this.handleChange = this.handleChange.bind(this);
}
handleChange(data){
// Here you should receive data change emitted from child components
}
render(){
...
<SelectBox id={selectBox.id} name={selectBox.name} selectBox={selectBox} onChange={this.handleChange}
}
}
Handle change listener should happen on the parent component, consider moving the fetch command to the parent instead. What you need to emit to parent is the event.target of the child
class SelectBox extends React.Component{
constructor(props) {
super(props);
this.state = { items: this.props.selectBox.items };
this.emitChange = this.emitChange.bind(this);
// Changed funciton's name to emitChange to avoid confusion
}
emitChange(event) {
const selectedValue = event.target.value;
const url = "/Home/" + event.target.dataset.childControllerMethod;
const data = JSON.stringify({ selectedValue: selectedValue });
fetch(url, {
method: 'post',
headers: {
'Accept': 'application/json, text/plain, */*',
'Content-Type': 'application/json'
},
body: data
}).then(response => {
if (response.status >= 400) {
console.log("Bad response from server");
}
return response.json();
}).then(data => {
// While you could keep this here, it can be sent to parent, it's your decision
if(!!this.props.onChange){
// Here you'll emit data to parent via a props function
this.props.onChange(data);
}
});
}
render() {
const optionItems = this.state.items.map((item, index) =>
<option key={index} value={item.value} >{item.text}</option>
);
return <div>
<label htmlFor={this.props.selectBox.id} >{this.props.selectBox.title}</label>
<select onChange={this.emitChange} id={this.props.selectBox.id} ref={this.props.selectBox.child} /*data-child={this.props.selectBox.child}*/ data-child-controller-method={this.props.selectBox.childControllerMethod}>
{optionItems}
</select>
</div>
}
};
ReactDOM.render(<MapControls />,
document.getElementById('mapControls')
);
So, this is the general idea, you pass from parent a prop that's a function binded to it (parent), child will have a method that will execute the prop (if exists).
What I left out of this example:
You need to consider where to handle the fetch command accordingly (parent or child), remember that state defined in constructors is not updated if props change.
IF you want state to update on component's prop changes you'll have to use event cycles like "componentWillReceiveProps" (deprecated in recent version) or similar.
My general recommendation is child components should dwell on props, whereas parent component should handle state to be passed to child as props.
Passing function handles as props is a good way to intercommunicate your components, you could also use RXJS and pass Subscription types as props.
So the solution I found is as follows. Thank you to Gabriel for pointing me in the right direction. The final solution could be used for any filter component that needs to react to users' selections
I followed Gabriel's recommendation to call the parent's onChange event and handle the setting of the state in there.
I created the triggerSibling method so that I could hook into the componentDidUpdate() event and cascade the changes down the hierarchy of select boxes. So the onChange and componentDidMount events trigger the same logic.
Then in the MapControls onChange, I followed Gabriel's suggestion to handle the data there.
In the call to the parent's onChange event, I pass the data from the api call, along with the name of the child to target
The children of the parent component are accessible through this.refs and I discovered that I can access the specific child by using its name as a key in the array of children, as follows
this.refs[data.child].setState({ items: data.items })
I used the componentDidMount() event to set the initial value of the first selectBox and trigger the cascade of updates on the initial load
MapControls component:
class MapControls extends React.Component {
constructor(props) {
super(props); // needed
this.state = {
selectBoxes: [
{
id: 'WorkSource',
name: 'WorkSource',
title: 'Work Source',
containerId: 'WorkSourceContainer',
className: 'WorkSource',
childControllerMethod: 'GetBusinessTypeDropdown',
items: [{ value: 0, text: 'Select' }, { value: 'ROUTED', text: 'Routed' }],
child: 'BusinessType'
},
{
id: 'BusinessType',
name: 'BusinessType',
title: 'Business Type',
containerId: 'BusinessTypeContainer',
className: 'BusinessType',
childControllerMethod: 'GetWorkTypeDropdown',
items: [{ value: 0, text: 'Select' }],
child: 'WorkType'
},
... more ...
]
}
this.handleChange = this.handleChange.bind(this);
}
handleChange(data) {
this.refs[data.child].setState({ items: data.items });
}
render() {
return this.state.selectBoxes.map(selectBox =>
<div key={selectBox.id} className='col-xs-2'>
<div id={selectBox.containerId}>
<SelectBox id={selectBox.id} name={selectBox.name} ref={selectBox.name} selectBox={selectBox} onChange={this.handleChange} />
</div>
</div>
);
}
};
SelectBox component:
class SelectBox extends React.Component{
constructor(props) {
super(props);
this.state = { items: this.props.selectBox.items };
this.emitChange = this.emitChange.bind(this);
}
triggerSibling (idOfDropdownToUpdate, selectedValue, url) {
const data = JSON.stringify({ selectedValue: selectedValue });
fetch(url, {
method: 'post',
headers: {
'Accept': 'application/json, text/plain, */*',
'Content-Type': 'application/json'
},
body: data,
}).then(response => {
if (response.status >= 400) {
console.log("Bad response from server");
}
return response.json();
}).then(data => {
if (!!this.props.onChange) {
// add the target to be updated as `child` property in the data passed to the parent
this.props.onChange({ child: this.props.selectBox.child, items: data });
}
});
}
componentDidMount() {
// Set the value of the first selectBox AFTER it has mounted, so that its `onChange` event is triggered and the `onChange` events cascade through the rest of the selectBoxes
if (this.props.name == "WorkSource") {
this.setState({ items: [{ value: 'ROUTED', text: 'Routed' }] });
}
}
// triggered when the component has finished rendering
componentDidUpdate(prevProps, prevState) {
const url = "/Home/" + this.props.selectBox.childControllerMethod;
if (this.props.selectBox.child != "")
this.triggerSibling(this.props.selectBox.child, this.state.items[0].value, url)
}
emitChange(event) {
const idOfDropdownToUpdate = event.target.dataset.child;
const selectedValue = event.target.value;
const url = "/Home/" + event.target.dataset.childControllerMethod;
this.triggerSibling(idOfDropdownToUpdate, selectedValue, url)
}
render()
{
const optionItems = this.state.items.map((item, index) =>
<option key={index} value={item.value} >{item.text}</option>
);
return <div>
<label htmlFor={this.props.selectBox.id} >{this.props.selectBox.title}</label>
<select onChange={this.emitChange} id={this.props.selectBox.id} data-child={this.props.selectBox.child} data-child-controller-method={this.props.selectBox.childControllerMethod}>
{optionItems}
</select>
</div>
}
};
I try to fill in a dropdown with data from the JSON format but for now the dropdown is empty (no results found...)
I certainly have a mistake and I can not understand where I'm confusing.
I will attach a screen of my API.
I want to get Station and NameStation..
API for Stations
My code:
import React, { Component } from 'react';
import Select from 'react-select';
import 'react-select/dist/react-select.css';
function parseStations(stations){
return stations.map((station) => {
return { label: station.NameStation, value: station.Station };
});
}
export default class Weather extends Component {
constructor(props) {
super(props);
this.state = {
options: [
{ value: true, label: 'Yes' },
{ value: false, label: 'No' }
], stations: [
],
value: null
}
this.onChange = this.onChange.bind(this);
}
onChange(event) {
this.setState({ value: event.value });
console.log('Boolean Select value changed to', event.value);
}
componentDidMount() {
this.getStations();
}
getStations() {
fetch('http://localhost:56348/api/stations', {
data: 'Station',
data: 'NameStation',
method: "GET"
}).then(res => res.json())
.then(res => this.setState({ stations: parseStations(res.stations) }))
//.then(res => this.setState({ stations: res.stations }))
//.catch(e => )
}
render() {
return (
<div className="MasterSection">
<div className="wrapper">
<div className="section">Изберете № на станция</div>
<Select
onChange={this.onChange}
//options={this.state.options}
options={this.state.stations}
value={this.state.value}
clearable={false}
/>
</div>
<div class="section">
<input type="text" class="form-control" placeholder="Брой дни назад" aria-label="Username" aria-describedby="basic-addon1"></input>
</div>
<div class="section">
<button type="button" class="btn btn-outline-dark">Покажи</button>
</div>
</div>
);
}
}
Seems you made a typo naming the prop stations instead of options :
<Select
onChange={this.onChange}
options={this.state.stations} // here
value={this.state.value}
clearable={false}
/>
Edit : you'll need to parse your json first to pass a proper array of objects like this : [{ label: nameStation, value: Station }]
Edit 2 : Here's a parser for your data :
function parseStations(stations){
return stations.map((station) => {
return { label: station.NameStation, value: station.Station };
});
}
You can call this in your async request before setting the state :
.then(res => this.setState({ stations: parseStations(res.stations) }))
componentDidMount() is executed only after render() is completed. so there's no way getStations() gets executed at the time your UI gets rendered. it is not a good idea to setState inside componentDidMount() as it triggers re rendering. use componentWillMount() instead.
correct the typo that Dyo mentioned and use options={this.state.stations}
For learning purpose I am writing a small app with a wizard in ReactJS.
I have created some components for the wizard as follow;
ProgressBar
Wizard
WizardStepOne
WizardStepOneForm
WizardStepTwo
WizardStepTwoForm
In the wizard component I have included my PorgressBar compnent for showing progression and created a switch statement to determine the oneClick value of the button included in each 'StepForm' to get a value and showing the next 'WizardStepTwoForm' component.
This all works well and does exactly what I expect but I am facing one problem. I don't want the user is able to get the next 'WizardStepTwoForm' form before I have validated the 'WizardStepOneForm'. So some how I should return a status to my parent component to determine if the user can click to the next state. Or, I disable the button by a state till a validation has been done but in this case the user won't be able to click on the button for an validation of the form.
During the submission of the form I want to send the data to the API, the dispatch is working but I am just wondering how to work it out right so my switch statement in the parent(Wizard) will only be fired if the form is valid.
Wizard
//.. imports
class Wizard extends React.Component {
constructor(props) {
super(props);
this.state = {
step : 'stepOne',
progression : '0%'
};
this.handleFormSubmit = this.handleFormSubmit.bind(this);
}
componentDidMount() {
const wizard = JSON.parse(localStorage.getItem('wizard'));
if (wizard !== null) {
this.setState({
step: wizard.step,
progression: wizard.progression
});
}
}
componentDidUpdate() {
localStorage.setItem('wizard', JSON.stringify({
step : this.state.step,
progression : this.state.progression
}));
}
handleFormSubmit(e) {
switch (e.target.value) {
case 'stepOne' :
this.setState({
step : 'stepOne',
progression : '0%',
});
break;
case 'stepTwo' :
this.setState({
step : 'stepTwo',
progression : '50%'
});
break;
}
}
/**
*
* Render
* #return {JSX}
*/
render() {
const { step, progression } = this.state;
switch (step) {
case 'stepOne' :
return (
<div>
<Header />
<WizardProgressBar progression={progression} stepOne="active" stepTwo="" />
<WizardStepOne handleFormSubmit={this.handleFormSubmit} />
<Footer/>
</div>
);
break;
case 'stepTwo' :
return (
<div>
<Header />
<WizardProgressBar progression={progression} stepOne="done" stepTwo="active" />
<WizardStepTwo handleFormSubmit={this.handleFormSubmit} />
<Footer/>
</div>
);
break;
}
}
}
export default Wizard;
WizardStepOne
export default class WizardStepOne extends React.Component {
constructor(props) {
super(props);
}
/**
*
* Render
* #return {XML}
*/
render() {
return(
<div className="step-one">
<h1>Step 1</h1>
<WizardStepOneForm handleFormSubmit={this.props.handleFormSubmit} />
</div>
);
}
}
WizardStepForm
//... imports
#connect((store) => {
return {
};
})
export default class WizardStepOneForm extends React.Component {
constructor(props) {
super(props);
this.state = {
formData : {
firstName : '',
lastName : '',
},
formErrors : {
firstName : true,
lastName : true,
},
formErrorMessages : {
firstName : 'some validation message',
lastName : 'some validation message',
},
formButtonEnabled : true,
}
this.handleSubmit = this.handleSubmit.bind(this);
this.handleFirstNameChange = this.handleFirstNameChange.bind(this);
this.handleLastNameChange = this.handleLastNameChange.bind(this);
}
componentDidMount() {
const stepOne = JSON.parse(localStorage.getItem('stepOne'));
if (stepOne !== null) {
this.setState({
formData : stepOne.formData,
formErrors : stepOne.formErrors,
formErrorMessages : stepOne.formErrorMessages,
});
}
}
handleFirstNameChange(e) {
let formData = this.state.formData;
let formErrors = this.state.formErrors;
let formErrorMessages = this.state.formErrorMessages;
formData.firstName = e.target.value;
if (!e.target.value) {
formErrors.firstName = true;
} else {
formErrors.firstName = false;
}
this.setState({ formData : formData, formErrors : formErrors, formErrorMessages : formErrorMessages });
localStorage.setItem('stepOne', JSON.stringify({ formData : formData, formErrors : formErrors, formErrorMessages : formErrorMessages }));
}
handleLastNameChange(e) {
let formData = this.state.formData;
let formErrors = this.state.formErrors;
let formErrorMessages = this.state.formErrorMessages;
formData.lastName = e.target.value;
if (!e.target.value) {
formErrors.lastName = true;
} else {
formErrors.lastName = false;
}
this.setState({ formData : formData, formErrors : formErrors, formErrorMessages : formErrorMessages });
localStorage.setItem('stepOne', JSON.stringify({ formData : formData, formErrors : formErrors, formErrorMessages : formErrorMessages }));
}
handleSubmitButton() {
}
handleSubmit(e) {
e.preventDefault();
this.props.dispatch(addUser(this.state.formData));
}
/**
*
* Render
* #return {XML}
*/
render() {
const firstNameError = this.state.formErrors.firstName ? 'error' : '';
const lastNameError = this.state.formErrors.lastName ? 'error' : '';
return(
<form className="step-one-form">
<div className="form-group right">
<div className="form-group__form-row">
<p className={classnames('col-2', firstNameError)}>
<label htmlFor="first_name">First name:</label>
<input type="text" id="firstName" name="fist_name" autoComplete="off" onChange={this.handleFirstNameChange} value={this.state.formData.firstName} />
{ firstNameError ? <FormElementErrorMessage message={this.state.formErrorMessages.firstName} /> : '' }
</p>
<p className={classnames('col-2', lastNameError)}>
<label htmlFor="last_name">Last name:</label>
<input type="text" id="lastName" name="last_name" autoComplete="off" onChange={this.handleLastNameChange} value={this.state.formData.lastName} />
{ lastNameError ? <FormElementErrorMessage message={this.state.formErrorMessages.lastName} /> : '' }
</p>
</div>
</div>
<button disabled={this.state.formButtonEnabled} onClick={this.props.handleFormSubmit} value="stepTwo">Next step</button>
</form>
);
}
}
So, I found out it's probably more easy as I thought.
The form submit handler comes in the child component where the form is created. So we don't need to push it downwards from the parent as a prop.
As we will fire an action via the dispatcher when the form 'stepOne' is valid, we change the given state by the reducer. The store receives this state change, which has been appended via connect and the provider at the root of our app, the parent component will receive this state change and we can fire up the next wizard screen.
So I have this function:
send_data({ pathname, data })
{
$.ajax({
url: "src/php/search.php",
beforeSend: () =>{
// this.props.dispatch( { type: "set_loading", payload: true } );
},
data: {
type: "write_report",
part: pathname,
data
},
method: "post",
success: (r) =>
{
console.log("I am sending the data and getting something back")
console.log(r);
console.log("after r");
// this.props.dispatch( { type: "set_loading", payload: false } );
Important>> this.props.dispatch({ type: "set_report", payload: JSON.parse(r) });
}
})
}
What it does is that it sends some data to a php backend, which then responds with a json string, which I parse to create an object from.
This is my reducer code:
const componentReducer = (state = default_component, action) => {
switch(action.type)
{
case "set_report":
{
state = {...state, report: action.payload};
break;
}
}
return state;
I know the store is updating as when I print this.props.report (the object I'm currently using) it gets something different before and after:
Before:
Object {assessors=[3], report=Object, risks=[4], ...}
After:
Object {assessors=[2], report=Object, risks=[4], ...}
However the display does not update.
But!!! If I dispatch an empty object {}
this.props.dispatch({ type: "set_report", payload: {} });
it does re-render the component (I also have some code that checks whether or not the report object is empty and will thusly, return me an object)
Rendering component info (for brevity, things are missing):
add_repeat(default_user)
{
this.repeats.push(<StartMultiple key={this.count} default_user={default_user} users={this.props.users} id={this.count} delete_this={this.delete_this} />);
this.setState({ repeats: this.repeats });
this.count++;
}
render()
{
return(
<div>
<p><b>Date</b></p>
<span>Select the date when assessment was performed:</span>
<input id="datepicker" name="datepicker" type="text" readOnly/>
<div>
(<i>If the select is empty, but you know there should be someone in it. That person may be no longer at the institute. If that person should exist, please notify ITS.</i>)
</div>
<div>
{this.state.repeats}
</div>
<button className="btn btn-default" onClick={this.add_repeat.bind(this, "none")}>Add Assessor</button>
</div>
);
}
}
const Start = connect(
(store) =>
{
return {
number: store.component.number,
report_id : store.component.report_id,
assessors: store.component.report.assessors,
users: store.component.users,
date: store.component.report.report.date,
};
}) (StartComponent);
export default Start;
Child component:
render()
{
var { users } = this.props;
users = {"none": "", ...users};
return(
<div>
<p><b>Assessor</b></p>
<select name="assessor" defaultValue={this.props.default_user}>
{ Object.keys(users).map( (key, index) => <option key={index} value={users[key]}>{users[key]}</option> ) }
</select>
<span style={{ display : "inline-block", paddingLeft : "10px"}}>
<button className="btn btn-default" onClick={this.delete_this.bind(this, this )}>Delete</button>
</span>
</div>
);
}
I have a searchForm component that renders a searchResult component. When the searchForm gets the results, it should pass the state to the result's state.
This where I fail.
var SearchForm = React.createClass({
getInitialState: function () {
return {
golden_record: {}
}
},
handleSearchSubmit: function (search_param) {
$.ajax({
url: this.props.url_variation,
type: 'GET',
data: search_param,
success: function (data) {
this.setState(
{
...
}
);
}.bind(this),
});
$.ajax({
url: this.props.url_golden,
type: 'GET',
data: search_param,
success: function (data) {
var golden_record = {
'site': data.sites[0].name,
'country': data.sites[0].country,
};
this.setState({'golden_record': golden_record});
}.bind(this),
})
},
render: function () {
return (
<div className="searchResult">
<SearchResult
golden_record={this.state.golden_record}
/>
</div>
);
}
});
SearchResult:
As you can see I am passing the golden_record as a property to the SearchResult. Inside SearchResult, when I set value of <input /> to the property this.props.golden_record['site'], the input is fixed to that value. But I want to set value rather to this.state.site so that I can change it afterwards, if I wanted to. So I don't know how to copy the read-only value of the prop to the state.
<input type="text" className="form-control" placeholder="Facility name" name="facilityName" onChange={this.onSiteChanged} value={this.props.golden_record['site']} ref="facilityName"></input>
Any suggestions please?
In your SearchResult component, you could set your state in componentWillReceiveProps:
var SearchResult = React.createClass({
...
getInitialState: function(){
return {
site: ''
}
},
componentDidMount: function(){
this.setState({ site: this.props.golden_record.site });
},
componentWillReceiveProps: function(newProps){
this.setState({ site: newProps.golden_record.site });
},
render: function(){
return <input type="text" className="form-control" placeholder="Facility name" name="facilityName" onChange={this.onSiteChanged} value={this.state.site} ref="facilityName"></input>
}
});