Reactjs Pops undefined in component - javascript

I have created react components for a form. I passed data as props from GetSteps component to PageHeader component. Then I will able to use that data from the PageHeader. Also I passed same data from the GetSteps component to YourDetails component. But the data didn't pass to the YourDetails component. I cannot find the error. any help will be appreciated. Thank You.
class GetSteps extends React.Component {
constructor(props) {
super(props);
this.state = {data: ''}
}
// componentWillMount() {
// var lang = [];
// $.each(this.props.value.Languages, function(k, v) {
// return lang[k] = v;
// }.bind(this));
// this.setState({ data: this.props.value.Languages })
//
// console.log(this.state)
// }
render()
{
return (
<div className="page-content">
<div className="container">
<PageHeader title={this.props.value.Title} subtitle={this.props.value.SubTitle} f={this.props.value.PreferredLanguage}/>
<YourDetails title={this.props.value.Title} preferredlang={this.props.value.PreferredLanguage}></YourDetails>
</div>
</div>
);
}
}
this is where I pass data as props
function PageHeader(props){
return(
<div className="page-header">
<span className="page-header-icon icon-world"></span>
<h3 className="title">{props.title}</h3>
<h4 className="sub-title special">{props.subtitle}</h4>
</div>
);
}
this is where I get data from GetSteps component
class YourDetails extends React.Component {
constructor(props) {
super(props);
this.state = {
havePartner: 'yes',
UserFirstName: "",
TravelPartnerName: "",
AmwayLocation: "",
Title: this.props.title
};
console.log(this.props);
this.handleInputChange = this.handleInputChange.bind(this);
this.handleOptionChange = this.handleOptionChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleSubmit(event){
console.log(this.state);
event.preventDefault();
}
handleInputChange(event) {
const target = event.target;
const value = target.type === 'radio' ? target.checked : target.value;
const name = target.name;
this.setState({
[name]: value
});
}
handleOptionChange(event){
this.setState({
havePartner: event.target.value
});
}
render() {
return (
<div className="main-content">
<form onSubmit={this.handleSubmit}>
<div className="field dropdown requiredField">
<label className="left">
Your prefered language
</label>
<div className="middleColumn">
<select name="language"
value={this.props.preferredlang}
onChange={this.handleInputChange}
className="dropdown requiredField align--left">
<option defaultValue value={this.props.preferredlang}>{this.props.preferredlang}</option>
<option value='g'></option>
<option value='fdg'></option>
<option value='df'></option>
<option value='dfg'></option>
</select>
</div>
</div>
<div className="field requiredField align--left">
<label>
Your First Name
</label>
<input
name="UserFirstName"
type="text"
onChange={this.handleInputChange} />
</div>
<div className="field optionset requiredField travel-partner align--left">
<label className="left">
Did you have a travel partner?
</label>
<ul className="optionset requiredField travel-partner align--left">
<li>
<input type="radio" value="yes" checked={this.state.havePartner === 'yes'} onChange={this.handleOptionChange} className="radio"/>
<label>Yes</label>
</li>
<li>
<input type="radio" value="no" checked={this.state.havePartner === 'no'} onChange={this.handleOptionChange } className="radio"/>
<label>No</label>
</li>
</ul>
</div>
<div className="field text requiredField align--left">
<label className="left">
Your travel partner's first name
</label>
<input className="text requiredField align--left"
name="TravelPartnerName"
type="text"
onChange={this.handleInputChange} />
</div>
<div className="field text">
<label className="left requiredField">*Required Field</label>
</div>
<div className="Actions">
<button type="submit" value="Submit" className="action nolabel " >
<span>Proceed to Day 1</span>
<span className="progress"></span>
</button>
</div>
</form>
</div>
);
}
}
this is where I didn't get data from GetSteps component
class Step extends React.Component {
constructor(props) {
super(props);
this.state = {data: ''}
}
componentWillMount() {
var link = document.getElementById('step').getAttribute('link');
$.getJSON( link+"VideoBuildForm", function( data, status ) {
fieldValues.PreferredLanguage = data.compilation.PreferredLanguage;
fieldValues.AmwayLocation = data.location;
fieldValues.Languages =
$.each(data.languages, function(k, v) {
return data.languages[k] = v;
});
fieldValues.Title = data.title;
fieldValues.SubTitle = data.subtitle;
this.setState({ data: fieldValues });
}.bind(this));
}
render() {
return (
<div>
<GetSteps value={this.state.data}/>
</div>
);
}
}
this is where I pass data to the GetSteps component

Try using props.title in your constructor instead of this.props.title.

Related

filtered data not getting pass from parent component to child component in React

this is how components are look like, i have 3 component that involves in this task, whenever i choose diffrent select dropdown option which is in filter component, change method in parent componet gonna fired and that gonna call another method also in parent component which filterData. its filtering the data but some how after setting state i am not getting filtered data in child component. so i can show filterd data
//parent component
import React, { Component } from 'react';
import ListingsData from '../data/data';
import Listings from '../listings/listings.component';
import Filter from '../filters/filter.component';
import './main_content.styles.scss';
class Main_content extends Component {
constructor(props) {
super();
this.state = {
listingsData: ListingsData,
searchOnChange: '',
filterdProperties: ListingsData,
}
}
change = (e) => {
this.setState({
[e.target.name] : e.target.value
}, () => {
this.filterData();
}
)
}
filterData = () => {
let newData = this.state.listingsData.filter(property => {
return property.type.toLowerCase().toString() === this.state.houseType.toLowerCase().toString()
})
this.setState({ filterdProperties: newData }, () => {
console.log(this.state)
});
}
render() {
return (
<div className='main-content'>
<div className='listings-container'>
<Listings ListingsData={ this.state.filterdProperties } />
</div>
<div className='filter-sidebar'>
<Filter filterTypeHouse={this.change} />
</div>
</div>
);
}
}
export default Main_content;
//child component Listing.component.jsx
import React, {Component} from 'react';
import './listings.styles.scss';
import Listing from '../listing/listing.component'
class Listings extends Component {
constructor(props) {
super(props);
this.state = {
listings: props.ListingsData
}
}
render() {
if (this.state.listings === undefined || this.state.listings.length === 0) {
return <h2>sorry no data found</h2>
}
return (
<div className='listings'>
{this.state.listings.map(({ id, image, address, price, city, rooms, bathrooms, area }) => (
<Listing key={id} image={image} address={address} price={price} city={city} rooms={rooms} bathrooms={bathrooms} area={area} />
))}
</div>
)
}
}
export default Listings;
//child component filter.component.jsx
import React from 'react';
import './filter.styles.scss';
let Filter = (props) => (
<div className='filter'>
<div className='type'>
<label htmlFor='propertyType'>Type</label>
<select className='propertyType' name='houseType' onChange={props.filterTypeHouse} >
<option value='any'>Any</option>
<option value='family-house'>Family House</option>
<option value='single-house'>Single house</option>
<option value='apartment'>Apartment</option>
<option value='villa'>Villa</option>
<option value='office-building'>Office Building</option>
<option value='condo'>Condo</option>
</select>
</div>
<div className='location'>
<label htmlFor='PropertyLocation'>Location</label>
<select className='PropertyLocation'>
<option>Any</option>
<option>New york</option>
<option>California</option>
<option>Washington</option>
<option>philedelphia</option>
<option>Boston</option>
</select>
</div>
<div className='min-price'>
<label htmlFor='priceFrom'>Min-Price</label>
<input type='text' className='priceFrom' placeholder='min-price' />
</div>
<div className='max-price'>
<label htmlFor='priceTo'>Max-Price</label>
<input type='text' className='priceTo' placeholder='max-price' />
</div>
<div className='dealOption'>
<label htmlFor='options'>Type Of Deal</label>
<div className='options'>
<div className='each_option'>
<label htmlFor='any'>Any</label>
<input type='radio' name='dealType' className='any' value='any' />
</div>
<div className='each_option'>
<label htmlFor='sale'>Sale</label>
<input type='radio' name='dealType' className='sale' value='sale' />
</div>
<div className='each_option'>
<label htmlFor='rent'>Rent</label>
<input type='radio' name='dealType' className='rent' value='rent' />
</div>
</div>
</div>
</div>
)
export default Filter;
The component that you use for rendering the filtered lists (Listings) is rendering based on state as per below code.
constructor(props) {
super(props);
this.state = {
listings: props.ListingsData
}
}
The constructor is called only once when the component is mounted. So, the state will never get modified from the initial state, even if you pass new filtered props. To avoid this behaviour, use the props to display the listings data.
So you can change your Listings component to render from props.
class Listings extends React.Component {
render() {
const {ListingData:listings} = this.props;
if (listings === undefined || listings.length === 0) {
return <h2>sorry no data found</h2>
}
return (
<div className='listings'>
{listings.map(({ id, ...props}) => (
<div key={id}>
{JSON.stringify(props)}
</div>
))}
</div>
)
}
}
Try out the below SO snippet. Change the dropdown to apartment, villa, condo to see the filtered data being rendered.
const ListingsData = [
{ type: "apartment", location: "New york" },
{ type: "apartment", location: "New york" },
{ type: "apartment", location: "New york" },
{ type: "villa", location: "New york" },
{ type: "condo", location: "New york" },
{ type: "condo", location: "Washington" }
];
let Filter = props => {
return (
<div className="filter">
<div className="type">
<label htmlFor="propertyType">Type</label>
<select
className="propertyType"
name="houseType"
onChange={props.filterTypeHouse}
>
<option value="any">Any</option>
<option value="family-house">Family House</option>
<option value="single-house">Single house</option>
<option value="apartment">Apartment</option>
<option value="villa">Villa</option>
<option value="office-building">Office Building</option>
<option value="condo">Condo</option>
</select>
</div>
<div className="location">
<label htmlFor="PropertyLocation">Location</label>
<select className="PropertyLocation">
<option>Any</option>
<option>New york</option>
<option>California</option>
<option>Washington</option>
<option>philedelphia</option>
<option>Boston</option>
</select>
</div>
<div className="min-price">
<label htmlFor="priceFrom">Min-Price</label>
<input type="text" className="priceFrom" placeholder="min-price" />
</div>
<div className="max-price">
<label htmlFor="priceTo">Max-Price</label>
<input type="text" className="priceTo" placeholder="max-price" />
</div>
<div className="dealOption">
<label htmlFor="options">Type Of Deal</label>
<div className="options">
<div className="each_option">
<label htmlFor="any">Any</label>
<input type="radio" name="dealType" className="any" value="any" />
</div>
<div className="each_option">
<label htmlFor="sale">Sale</label>
<input type="radio" name="dealType" className="sale" value="sale" />
</div>
<div className="each_option">
<label htmlFor="rent">Rent</label>
<input type="radio" name="dealType" className="rent" value="rent" />
</div>
</div>
</div>
</div>
);
}
class Listings extends React.Component {
render() {
const {ListingData:listings} = this.props;
if (listings === undefined || listings.length === 0) {
return <h2>sorry no data found</h2>
}
return (
<div className='listings'>
{listings.map(({ id, ...props}) => (
<div key={id}>
{JSON.stringify(props)}
</div>
))}
</div>
)
}
}
class Main_content extends React.Component {
constructor(props) {
super();
this.state = {
listingsData: ListingsData,
searchOnChange: '',
filterdProperties: ListingsData,
}
}
change = (e) => {
console.log("Calling change handler");
this.setState({
[e.target.name] : e.target.value
}, () => {
this.filterData();
}
)
}
filterData = () => {
console.log("Calling filter data");
let newData = this.state.listingsData.filter(property => {
return property.type.toLowerCase().toString() === this.state.houseType.toLowerCase().toString()
})
this.setState({ filterdProperties: newData }, () => {
console.log("State", this.state);
});
}
render() {
return (
<div className="main-content">
<div className="listings-container">
<Listings ListingData={this.state.filterdProperties} />
</div>
<div className="filter-sidebar">
<Filter filterTypeHouse={this.change} />
</div>
</div>
);
}
}
ReactDOM.render(<Main_content />,document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>

How can I append objects to the body of a component in React?

I am trying to set up some functionality on this React component so that a user can add and remove empty radio button options to a page that a user can type text into. The only issue that I am having is that I am relatively new to React and am not 100% how to do this.
import React, { Component } from 'react';
class TextRadio extends Component {
constructor() {
super();
state = {
textValue: ""
}
};
handleInputChange = event => {
const value = event.target.value;
const name = event.target.name;
this.setState({
[name]: value
});
}
addBox = () => {
}
removeBox = () => {
}
render() {
return(
<div>
<div className="form-check">
<input className="form-check-input" type="radio" id="" name="" value="" />
<label className="form-check-label" for="">
<input class="form-control" type="text" placeholder="" />
</label>
</div>
<div className="form-check">
<input className="form-check-input" type="radio" id="option" name="option" value="option" />
<label className="form-check-label" for="option">
<input class="form-control" type="text" placeholder="" />
</label>
</div>
<div className="form-check">
<input className="form-check-input" type="radio" id="option" name="option" value="option" />
<label className="form-check-label" for="option">
<input class="form-control" type="text" placeholder="" />
</label>
</div>
<button type="button" className="btn btn-primary" onClick={this.addBox}>
Add Option
</button>
<button type="button" className="btn btn-danger" onClick={this.removeBox}>
Remove Option
</button>
</div>
);
}
}
export default TextRadio;
The result that I am expecting to happen is to have it so the component can add and remove radio button options from the page depending on the button that the user presses
i was completed just your addBox and RemoveBox functions, i hope that's help you
import React, { Component } from "react";
class TextRadio extends Component {
constructor() {
super();
this.state = {
radioButtons: []
};
}
handleInputChange = event => {
const value = event.target.value;
const name = event.target.name;
};
addBox = () => {
this.setState(prevstate => {
let radioButtons = prevstate.radioButtons;
if (radioButtons.length === 0) {
radioButtons.push({
id: 1,
name: "radiobutton",
value: "test"
});
return {
radioButtons: radioButtons
};
} else {
radioButtons.push({
id: radioButtons[radioButtons.length - 1].id + 1,
name: "raiodButton_" + (radioButtons[radioButtons.length - 1].id + 1),
value: radioButtons[radioButtons.length - 1].value
});
return {
radioButtons: radioButtons
};
}
});
};
removeBox = () => {
this.setState(prevstate => {
let radioButtons = prevstate.radioButtons;
if (radioButtons.length !== 0) {
radioButtons.pop(radioButtons[radioButtons.length - 1]);
return {
radioButtons: radioButtons
};
} else {
return { radioButtons: radioButtons };
}
});
};
render() {
return (
<div>
<div className="form-check">
{this.state.radioButtons.map(radiobutton => {
return (
<div>
<input
className="form-check-input"
type="radio"
id={radiobutton.id}
name={radiobutton.name}
value={radiobutton.value}
/>
<label className="form-check-label" for="">
<input class="form-control" type="text" placeholder="" />
</label>
</div>
);
})}
</div>
<button type="button" className="btn btn-primary" onClick={this.addBox}>
Add Option
</button>
<button
type="button"
className="btn btn-danger"
onClick={this.removeBox}
>
Remove Option
</button>
</div>
);
}
}
export default TextRadio;
https://codesandbox.io/embed/confident-browser-tmojp
I was playing around with your idea and made some changes in the code, just to show you an example, how you can dynamically create new components and store them in applications state and then render out to user based on their actions.
I created new component just for form UI: option, input field and remove button. If user clicks on the Add Option, new item of the component is added to application state and then render out. Remove button is used to remove Item from state.
class TextRadio extends Component {
state = {
optionInputs: []
};
addBox = () => {
const optionInputsUpdated = [
...this.state.optionInputs,
<OptionInput id={uuid.v4()} remove={this.removeBox} />
];
this.setState({ optionInputs: optionInputsUpdated });
};
removeBox = id => {
const optionInputsUpdated = this.state.optionInputs.filter(
item => item.props.id !== id
);
this.setState({ optionInputs: optionInputsUpdated });
};
render() {
return (
<div>
{this.state.optionInputs.map((optionInput, idx) => {
return (
<div key={idx} test="123">
{optionInput}
</div>
);
})}
<button type="button" className="btn btn-primary" onClick={this.addBox}>
Add Option
</button>
</div>
);
}
}
const OptionInput = props => {
return (
<div className="form-check">
<input
className="form-check-input"
type="radio"
id=""
name="radio"
value=""
/>
<label className="form-check-label" for="">
<input className="form-control" type="text" placeholder="" />
</label>{" "}
<button
type="button"
className="btn btn-danger"
onClick={() => props.remove(props.id)}
>
Remove Option
</button>
</div>
);
};
Hope this gives you better understanding, how to achieve your goal.
If you need additional help, just post a comment under this answer, and I will update demo to help you.
Here is DEMO I created from your code: https://codesandbox.io/s/nice-ganguly-s4wls
first you have to initialize an empty array state
this.state={
radioButtons : [{input:''}]
}
then in your return statement you have to loop through the radioButtons array and show the radio button with input
{
this.state.radioButtons.map(item => (
<div className="form-check">
<input className="form-check-input" type="radio" id="option" name="option" value="option" />
<label className="form-check-label" for="option">
<input class="form-control" type="text" placeholder="" />
</label>
</div>
))
}
then in your addBox function append an object on every click
addBox = () => {
this.setState({radioButtons:[...this.state.radioButtons, {input:''}]})
}
function to remove a radio button object
removeBox = () => {
let radioArray = this.state.radioButtons
radioArray.pop()
this.setState({radioButtons:radioArray})
}
Final code Looks like this :
import React from "react";
import ReactDOM from "react-dom";
import "./styles.css";
class App extends React.Component{
constructor(props){
super(props);
this.state={
radioButtons :[{input:''}]
}
}
addBox = () => {
this.setState({radioButtons:[...this.state.radioButtons, {input:''}]})
}
removeBox = () => {
let radioArray = this.state.radioButtons
radioArray.pop()
this.setState({radioButtons:radioArray})
}
render(){
return(
<div>
{
this.state.radioButtons.map(item => (
<div className="form-check">
<input className="form-check-input" type="radio" id="option" name="option" value="option" />
<label className="form-check-label" for="option">
<input class="form-control" type="text" placeholder="" />
</label>
</div>
))
}
<button type="button" className="btn btn-primary" onClick={this.addBox}>
Add Option
</button>
<button type="button" className="btn btn-danger" onClick={this.removeBox}>
Remove Option
</button>
</div>
)
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
codepen Example

state is null after setting state in react [duplicate]

This question already has answers here:
ReactJS this.state null
(5 answers)
Closed 6 years ago.
I have a component in react that is a simple form, I have a function that looks if there is a change in any of the form elements and then sets the state of the form element being edited. In the handleChange function when I do console.log(this.state) I see the exact thing I expect, the correct keys eg (name, teamName etc) with the values in I have entered in the form.
However when I click submit and it calls the function nextStep I get an error message saying this.state.name is null, am I missing something here?
Here is my 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 = {
name: '',
teamName: '',
bio: '',
teamId: ''
};
this.handleChange = this.handleChange.bind(this);
}
handleChange(name, event) {
this.setState({[name]: event.target.value});
console.log(this.state);
}
nextStep(e) {
e.preventDefault();
// Get values via this.refs
var player = {
id: uuid(),
name: this.state.name,
teamName: this.state.teamName,
bio: this.state.bio,
teamId: this.state.teamId
};
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.state.name} onChange={this.handleChange.bind(this, 'name')}/>
</div>
<div className="form-group">
<label className="control-label">Team Name</label>
<input type="text" className="form-control" ref="teamName" defaultValue={this.state.teamName} onChange={this.handleChange.bind(this, 'teamName')}/>
</div>
<TeamSelectBox state={this.state.teamId} onChange={this.handleChange.bind(this, 'teamId')}/>
<div className="form-group">
<label className="control-label">Bio</label>
<input type="textarea" className="form-control" ref="bio" defaultValue={this.state.bio} onChange={this.handleChange.bind(this, 'bio')}/>
</div>
<div className="bs-component">
<button className="btn btn-md btn-default btn-block" onClick={this.nextStep}>Save & Continue</button>
</div>
</form>
</div>
</div>
</div>
</div>
)
}
}
module.exports = PlayerForm;
setState doesn't mutate the state immediately and hence you must make use of callback in setState to log the updated value
handleChange(name, event) {
this.setState({[name]: event.target.value}, function() {
console.log(this.state);
});
}
Also you did not bind the nextStep function. You should do that in the constructor or any other way you prefer
class PlayerForm extends React.Component {
constructor(props) {
super(props);
this.state = {
name: '',
teamName: '',
bio: '',
teamId: ''
};
this.handleChange = this.handleChange.bind(this);
this.nextStep = this.nextStep.bind(this);
}
handleChange(name, event) {
this.setState({[name]: event.target.value});
console.log(this.state);
}
nextStep(e) {
e.preventDefault();
// Get values via this.refs
var player = {
id: "9879",
name: this.state.name,
teamName: this.state.teamName,
bio: this.state.bio,
teamId: this.state.teamId
};
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.state.name} onChange={this.handleChange.bind(this, 'name')}/>
</div>
<div className="form-group">
<label className="control-label">Team Name</label>
<input type="text" className="form-control" ref="teamName" defaultValue={this.state.teamName} onChange={this.handleChange.bind(this, 'teamName')}/>
</div>
<div className="form-group">
<label className="control-label">Bio</label>
<input type="textarea" className="form-control" ref="bio" defaultValue={this.state.bio} onChange={this.handleChange.bind(this, 'bio')}/>
</div>
<div className="bs-component">
<button className="btn btn-md btn-default btn-block" onClick={this.nextStep}>Save & Continue</button>
</div>
</form>
</div>
</div>
</div>
</div>
)
}
}
ReactDOM.render(<PlayerForm/>, document.getElementById('app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.0/react-dom.min.js"></script>
<div id="app"></div>

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 & 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;
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!
i think you have a typo, you missed spell props, this.props not this.probs

How can you add styles in reactJs for show/hiding google maps?

I have three radio buttons which chooses school, restaurant and store. When clicking each, I would like to display the following nearby place whether it is school, restaurant or store. I have no problem on displaying the google map and its nearby places if I do it individually.
class PropertyMap extends React.Component{
constructor(props) {
super(props);
this.state = {
propertyType: 'default',
selectedOption: ''
}
this.handleClick = this.handleClick.bind(this);
}
handleClick(e){
this.setState({
propertyType: e.target.value
});
}
componentDidMount(){
let school = document.getElementById('school');
let restaurant = document.getElementById('restaurant');
let default = document.getElementById('default');
if(this.state.propertyType == 'restaurant'){
school.setAttribute('style', 'height:0');
restaurant.setAttribute('style', 'height:100%');
}
else if(this.state.propertyType == 'school'){
school.setAttribute('style', 'height:100%');
restaurant.setAttribute('style', 'height:0');
}
else{
school.setAttribute('style', 'height:0%');
restaurant.setAttribute('style', 'height:0');
default.setAttribute('style', 'height:100%');
}
}
render(){
let _standard = this.props.standard;
let datax = _standard.data;
let address = datax.address;
let city = datax.City;
let postcode = datax.Code;
let st = datax.State;
let defaultMap = (<DefaultMap mapdetails={datax} />);
let schoolMap = (<SchoolMap mapdetails={datax} type={this.state.propertyType} />);
let restaurantMap = (<RestaurantMap mapdetails={datax} type={this.state.propertyType} />);
return(
<div>
<div className="container">
<div className="row">
<div className="col-md-12">
<div className="location-info-container">
<h2>Location</h2>
<p>
{address}.
</p>
<p>
{city}, {st} {postcode}
</p>
<p><b>Nearby:</b></p>
<label className="radio-inline">
<input type="radio" name="map" id="" onChange={this.handleClick} value="school" /> School
</label>
<label className="radio-inline">
<input type="radio" name="map" id="" onChange={this.handleClick} value="restaurant" /> Restaurant
</label>
<label className="radio-inline">
<input type="radio" name="map" id="" onChange={this.handleClick} value="store" /> Store
</label>
</div>
</div>
</div>
</div>
<div id="gmap">
<div id="default">
{defaultMap}
</div>
<div id="restaurant">
{restaurantMap}
</div>
<div id="school">
{schoolMap}
</div>
</div>
</div>
)
}
}
Can anyone advise why the styles from my componentDidMount are not updating when I click any of the radio buttons? Basically, if I click school I want its height to be equal to 100% and the restaurant to be 0 and vice-versa.
Like I said in a comment before, componentDidMount only executes the first time when component is mounted. You can use componentWillUpdate or componentDidUpdate if you need to do something before and/or after a component update. See: https://facebook.github.io/react/docs/react-component.html
If you just want to show or hide a component with a radio button action, best practice in React could be something like this:
class PropertyMap extends React.Component {
constructor(props) {
super(props);
this.state = {
propertyType: 'default',
selectedOption: ''
}
this.handleClick = this.handleClick.bind(this);
}
handleClick(e){
this.setState({
propertyType: e.target.value
});
}
render() {
let map = <div>Your Default component here</div>;
switch (this.state.propertyType) {
case 'restaurant':
map = <div>Your Restaurant component here</div>;
break;
case 'school':
map = <div>Your School component here</div>;
break;
}
return(
<div>
<div className="container">
<div className="row">
<div className="col-md-12">
<div className="location-info-container">
<label className="radio-inline">
<input type="radio" name="map" id="" onChange={this.handleClick} value="school" /> School
</label>
<label className="radio-inline">
<input type="radio" name="map" id="" onChange={this.handleClick} value="restaurant" /> Restaurant
</label>
<label className="radio-inline">
<input type="radio" name="map" id="" onChange={this.handleClick} value="store" /> Store
</label>
</div>
</div>
</div>
</div>
<div id="gmap">{map}</div>
</div>
)
}
}
// Render it
ReactDOM.render(
<PropertyMap />,
document.getElementById("root")
);
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
But if you want to use the height method, maybe something like this is better (using style and class attribute)
class PropertyMap extends React.Component {
constructor(props) {
super(props);
this.state = {
propertyType: 'default',
selectedOption: ''
}
this.handleClick = this.handleClick.bind(this);
}
handleClick(e){
this.setState({
propertyType: e.target.value
});
}
render() {
const { propertyType } = this.state
return(
<div>
<div className="container">
<div className="row">
<div className="col-md-12">
<div className="location-info-container">
<label className="radio-inline">
<input type="radio" name="map" id="" onChange={this.handleClick} value="school" /> School
</label>
<label className="radio-inline">
<input type="radio" name="map" id="" onChange={this.handleClick} value="restaurant" /> Restaurant
</label>
<label className="radio-inline">
<input type="radio" name="map" id="" onChange={this.handleClick} value="store" /> Store
</label>
</div>
</div>
</div>
</div>
<div id="gmap">
{/*
<div style={{height: (propertyType === 'restaurant') ? '100%' : '0%'}}>Your Restaurant component here</div>
<div style={{height: (propertyType === 'school') ? '100%' : '0%'}}>Your School component here</div>
<div style={{height: (propertyType !== 'restaurant' && propertyType !== 'school') ? '100%' : '0%'}}>Your Default component here</div>
*/}
<div className={(propertyType === 'restaurant') ? 'show' : 'hide'}>Your Restaurant component here</div>
<div className={(propertyType === 'school') ? 'show' : 'hide'}>Your School component here</div>
<div className={(propertyType !== 'restaurant' && propertyType !== 'school') ? 'show' : 'hide'}>Your Default component here</div>
</div>
</div>
)
}
}
// Render it
ReactDOM.render(
<PropertyMap />,
document.getElementById("root")
);
.show {
width: 100%;
display: block;
}
.hide {
width: 0%;
display: none;
}
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
I could not upvote the comment earlier so I'll just post the solution here. As advised, I put all my code from the componentDidMount into the render function and it worked.

Categories