I have one component (Fuel) which I use in two other components (Search and SmallFilters) :
Search component is as follows :
class search extends React.Component {
render() {
const language = this.props.language.default.portal;
return (
<div>
<div className="searchTitle"><FontAwesome name="search" className="portalFaIcon"/> {language.search}</div>
<Fuel language={language} actionFilters={this.props.actionFilters} filters={this.props.filters}/>
</div>
);
}
}
function mapStateToProps(state, ownProps){
return {
favorites: state.favorites,
filters: state.filters,
carsToShow: state.carsToShow
};
}
function mapDispatchToProps(dispatch){
return {
actionFilters: bindActionCreators(filterActions, dispatch),
actionCarsToShow: bindActionCreators(actionCarsToShow, dispatch)
};
}
export default connect(mapStateToProps, mapDispatchToProps)(search);
The SmallFilters is as follows :
render(){
return (
<div className="filters noPadding col-xl-8 col-lg-6 col-md-6 col-sm-5 col-xs-12">
<ReactCSSTransitionGroup transitionName="example" transitionAppear={true} transitionAppearTimeout={500} transitionEnterTimeout={500} transitionLeaveTimeout={500}>
<Fuel recap={true} title={_.startCase(_.toLower(filter_names.fuel))} {...this.props}/>
</ReactCSSTransitionGroup>
</div>
);
}
The Fuel component is as follows :
import React from 'react';
import FontAwesome from 'react-fontawesome';
import {Link} from 'react-router';
import { filter_names } from './filterActions';
export default class fuel extends React.Component {
constructor(props){
super(props);
this.state = this.getFilterValues()
}
emptyValues(){
return {
checkboxDiesel: false,
checkboxBenzine: false
}
}
handleFilter(){
if(this.state.checkboxDiesel || this.state.checkboxBenzine){
this.props.actionFilters.addFuelFilter(this.state);
}else{
this.props.actionFilters.removeFuelFilter();
}
}
handleDiesel(event){
const checkbox = event.target.checked;
this.setState({checkboxDiesel: checkbox, checkboxBenzine: this.state.checkboxBenzine}, () => this.handleFilter());
}
handleBenzine(event){
const checkbox = event.target.checked;
this.setState({checkboxBenzine: checkbox, checkboxDiesel: this.state.checkboxDiesel}, () => this.handleFilter());
}
deActivate(event) {
event.preventDefault();
this.setState(this.emptyValues(), () => this.handleFilter());
}
getFilterValues(){
debugger;
if(!this.props.filters.some(i => i.name === filter_names.fuel)){
return this.emptyValues();
}
return {
checkboxDiesel: this.props.filters.filter(f => f.name === filter_names.fuel).map(i => i.values.map(v => v.checkboxDiesel)),
checkboxBenzine: this.props.filters.filter(f => f.name === filter_names.fuel).map(i => i.values.map(v => v.checkboxBenzine))
};
/*let values = {};
this.props.filters.filter(f => {
if(f.name == filter_names.fuel){
values.checkboxDiesel = f.values[0].checkboxDiesel;
values.checkboxBenzine = f.values[0].checkboxBenzine;
}
});
return values;*/
}
renderSmall() {
let diesel = this.getFilterValues().checkboxDiesel ? "Diesel" : "";
let benzine = this.getFilterValues().checkboxBenzine ? "Benzine" : "";
return (
<div className="filter">
{this.props.title} <Link to="" onClick={this.deActivate.bind(this)}><FontAwesome name="times" className="portalFaRedIcon"/></Link>
<div className="filterValues">{diesel} {benzine}</div>
</div>
);
}
render() {
const language = this.props.language;
if(this.props.recap) return this.renderSmall();
console.log(this.props.filters);
return (
<div>
<div className="priceTitle" style={{padding: '5px 0'}}>{language.fuel}</div>
<div className="transmissionValues">
<input type="checkbox" onChange={this.handleDiesel.bind(this)} checked={this.getFilterValues().checkboxDiesel}/> <span>Diesel</span>
</div>
<div className="transmissionValues">
<input type="checkbox" onChange={this.handleBenzine.bind(this)} checked={this.getFilterValues().checkboxBenzine}/> <span>Benzine</span>
</div>
</div>
);
}
}
The problem is, when I click on one of those checkboxes, both are checked. And If I click on the same checkbox both are unchecked. But if I click on the other one nothing happends.
This.props.filters comes from redux store and it's something like this if one of those checkboxes is checked :
[{name: "FUEL", values: [{checkboxDiesel: true, checkboxBenzine: false}]}]
Any advice?
By a long shot, I think you should just use this.state to update your input's value. Read controlled components from the docs.
render() {
const language = this.props.language;
if(this.props.recap) return this.renderSmall();
console.log(this.props.filters);
return (
<div>
<div className="priceTitle" style={{padding: '5px 0'}}>{language.fuel}</div>
<div className="transmissionValues">
<input type="checkbox" onChange={this.handleDiesel.bind(this)} checked={this.state.checkboxDiesel}/> <span>Diesel</span>
</div>
<div className="transmissionValues">
<input type="checkbox" onChange={this.handleBenzine.bind(this)} checked={this.state.checkboxBenzine}/> <span>Benzine</span>
</div>
</div>
);
}
If there are any side-effects of this action, you can do that in handleDiesel or handleBenzine methods. Let me know if it works. Meanwhile, I'll try to understand more from your code.
Related
I have the following example where the toggleComponent.js is working perfectly.
The problem here is that I don't want to render the <ContentComponent/> inside the toggle, rather I want the opposite, I want to toggle the <ContentComponent/> that will be called in another component depending on the state of the toggle.
So the <ContentComponent/> is outside the toggleComponent.js, but they are linked together. So I can display it externally using the toggle.
An image to give you an idea:
Link to funtional code:
https://stackblitz.com/edit/react-fwn3rn?file=src/App.js
import React, { Component } from "react";
import ToggleComponent from "./toggleComponent";
import ContentComponent from "./content";
export default class App extends React.Component {
render() {
return (
<div>
<ToggleComponent
render={({ isShowBody, checkbox }) => (
<div>
{isShowBody && <h1>test</h1>}
<button onClick={checkbox}>Show</button>
</div>
)}
/>
<ToggleComponent
render={({ isShowBody, checkbox }) => (
<div>
{isShowBody && (
<h1>
<ContentComponent />
</h1>
)}
<button onClick={checkbox}>Show</button>
</div>
)}
/>
</div>
);
}
}
Bit tweaked your source.
Modified ToggleComponent
import React from "react";
export default class ToggleComponent extends React.Component {
constructor() {
super();
this.state = {
checked: false
};
this.handleClick = this.handleClick.bind(this);
}
handleClick = () => {
this.setState({ checked: !this.state.checked });
this.props.toggled(!this.state.checked);
};
checkbox = () => {
return (
<div>
<label>Toggle</label>
<span className="switch switch-sm">
<label>
<input type="checkbox" name="select" onClick={this.handleClick} />
<span />
</label>
</span>
</div>
);
};
render() {
return this.checkbox();
}
}
Added OtherComponent with ContentComponent inside.
import React, { Component } from "react";
import ContentComponent from "./content";
export default class OtherComponent extends React.Component {
render() {
return <div>{this.props.show ? <ContentComponent /> : null}</div>;
}
}
Separated as per your requirement.
Modified App
import React, { Component, PropTypes } from "react";
import ToggleComponent from "./toggleComponent";
import OtherComponent from "./otherComponent";
export default class App extends React.Component {
constructor() {
super();
this.toggled = this.toggled.bind(this);
this.state = { show: false };
}
toggled(value) {
this.setState({ show: value });
}
render() {
return (
<div>
<ToggleComponent toggled={this.toggled} />
<OtherComponent show={this.state.show} />
</div>
);
}
}
Working demo at StackBlitz.
If you want to share states across components a good way to do that is to use callbacks and states. I will use below some functional components but the same principle can be applied with class based components and their setState function.
You can see this example running here, I've tried to reproduce a bit what you showed in your question.
import React, { useState, useEffect, useCallback } from "react";
import "./style.css";
const ToggleComponent = props => {
const { label: labelText, checked, onClick } = props;
return (
<label>
<input type="checkbox" checked={checked} onClick={onClick} />
{labelText}
</label>
);
};
const ContentComponent = props => {
const { label, children, render: renderFromProps, onChange } = props;
const [checked, setChecked] = useState(false);
const defaultRender = () => null;
const render = renderFromProps || children || defaultRender;
return (
<div>
<ToggleComponent
label={label}
checked={checked}
onClick={() => {
setChecked(previousChecked => !previousChecked);
}}
/>
{render(checked)}
</div>
);
};
const Holder = () => {
return (
<div>
<ContentComponent label="First">
{checked => (
<h1>First content ({checked ? "checked" : "unchecked"})</h1>
)}
</ContentComponent>
<ContentComponent
label="Second"
render={checked => (checked ? <h1>Second content</h1> : null)}
/>
</div>
);
};
PS: A good rule of thumb concerning state management is to try to avoid bi-directional state handling. For instance here in my example I don't use an internal state in ToggleComponent because it would require to update it if given checked property has changed. If you want to have this kind of shared state changes then you need to use useEffect on functional component.
const ContentComponent = props => {
const { checked: checkedFromProps, label, children, render: renderFromProps, onChange } = props;
const [checked, setChecked] = useState(checkedFromProps || false);
const defaultRender = () => null;
const render = renderFromProps || children || defaultRender;
// onChange callback
useEffect(() => {
if (onChange) {
onChange(checked);
}
}, [ checked, onChange ]);
// update from props
useEffect(() => {
setChecked(checkedFromProps);
}, [ checkedFromProps, setChecked ]);
return (
<div>
<ToggleComponent
label={label}
checked={checked}
onClick={() => {
setChecked(previousChecked => !previousChecked);
}}
/>
{render(checked)}
</div>
);
};
const Other = () => {
const [ checked, setChecked ] = useState(true);
return (
<div>
{ checked ? "Checked" : "Unchecked" }
<ContentComponent checked={checked} onChange={setChecked} />
</div>
);
};
I am new to react and I have a problem trying to take the information submitted in an input and return it as output outside the nav component, where it sits. I want the output to return to the Content component but I am having a hard time trying to figure out how to do that. Trying to return it as a prop returns as undefined. I have read the documentation and tried to find answer in videos but nothing seems to be solving the problem. Can anyone point me in the right direction?
// this is the root component
class App extends React.Component {
constructor(props) {
super(props)
this.state = {
userInput: ''
}
}
handleChange = (e) => {
this.setState({
userInput: e.target.value
})
}
render() {
const { userInput } = this.state
return (
<div className="recipes">
<Nav />
<Content userInput={this.state.userInput} changed={this.handleChange} />
</div>
)
}
}
// this is where the input is stored and where I want to take its value and return it to the the Content Component
class Nav extends React.Component {
state = {
userInput: ''
}
handleChange = (e) => {
this.setState({
userInput: e.target.value
})
}
render() {
return (
<nav className="nav">
<h1 className="title" >Nourish</h1>
<h2 className="title" >{this.state.userInput}</h2>
<input type="text" className="input" onChange={this.handleChange} />
</nav>
)
}
}
// this is where I want to output the value to
const Content = (props) => {
console.log(props.userInput)
return (
<h2 className="main"> {props.userInput} </h2>
)
}
you can create a simple input component but the value and event handlers come from the parent as props
look at this example
import React, { useState } from 'react'
import Input from './Input'
const App = () => {
const [InputOneValue, setInputOnValue] = useState("")
const [InputTwoValue, setInputTwoValue] = useState("")
const InputOneChangeHandler = (value) => {
setInputOneValue(value)
}
const InputTwoChangeHandle = (value) => {
setInputTwoValue(value)
}
const onSubmitHanlder = () {
// InputOneValue
// InputTwoValue
}
return (
<form onSubmit={submitHandler}>
<Input value={InputOneValue} changeHandler={InputOneChangeHandler}
<Input value={InputTwoValue} changeHandler={InputTwoChangeHandler}
</form>
)
}
export default App
and this is you Input component
const Input = (props) => {
return <input value={props.value} onChange={props.changeHandler} />
}
export default Input
You dont need to write handle change and not needed to store userInput in Nav. store directly in App.js . so in Nav instead of this.handleChange use this.props.changed this helps you store userInput in App then you can pass the data as props.
// this is the root component
class App extends React.Component {
constructor(props) {
super(props)
this.state = {
userInput: ""
}
}
handleChange = (e) => {
this.setState({
userInput: e.target.value
})
}
render() {
const { userInput } = this.state
return (
<div className="recipes">
<Nav userInput={this.state.userInput} />
<Content userInput={this.state.userInput} changed={this.handleChange} />
</div>
)
}
}
class Nav extends React.Component {
render() {
return (
<nav className="nav">
<h1 className="title" >Nourish</h1>
<h2 className="title" >{this.state.userInput}</h2>
<input type="text" className="input" onChange={this.props.changed} />
</nav>
)
}
}
// this is where I want to output the value to
const Content = (props) => {
console.log(props.userInput)
return (
<h2 className="main"> {props.userInput} </h2>
)
}
I was writing a component with the code given as follows, which after rendering looks like:
I have used antd components to render the fields. The problem that I am facing is that I am neither able to select from the select box nor write in the input field as shown below. I have a feeling that I am using React's key inappropriately for mocFields in the render method which is obtained from getMOCField.
import React, { Component } from "react";
import { Button, Icon, Select, Form, Input } from "antd";
const FormItem = Form.Item;
const Option = Select.Option;
import { FormComponentProps } from "antd/lib/form/Form";
type state = {
mocFields: JSX.Element[]
};
export class MOC extends Component<FormComponentProps, state> {
constructor(props) {
super(props);
this.state = {
mocFields: []
};
this.addMOCField = this.addMOCField.bind(this);
this.removeMOCField = this.removeMOCField.bind(this);
}
componentDidMount() {}
componentWillReceiveProps(nextProps) {}
removeMOCField(key, event: React.MouseEvent<HTMLElement>) {
event.preventDefault();
const { mocFields } = this.state;
mocFields.splice(key, 1);
this.setState({
mocFields
});
}
getMOCFieldFooter() {
return (
<div className="d-flex justify-content-between small">
<div className="inline-block">
<Button
type="primary"
shape="circle"
icon="plus"
ghost
size="small"
className="d-font mr-1"
onClick={this.addMOCField}
/>
<div
className="text-primary pointer d-font inline-block letter-spacing-1"
onClick={this.addMOCField}
>
Add another
</div>
<div className="d-font inline-block letter-spacing-1">or </div>
<div className="text-primary pointer d-font inline-block letter-spacing-1">
Create a new MOC
</div>
</div>
</div>
);
}
getMOCField(key) {
const { getFieldDecorator } = this.props.form;
return (
<div className="d-flex justify-content-between">
<div className="inline-block">
<FormItem label="Select MOC">
{getFieldDecorator(`selected_moc[${key}]`, {
rules: [
{
required: true,
message: "Please select moc"
}
]
})(
<Select>
<Option value={"A"}>A</Option>
<Option value={"B"}>B</Option>
</Select>
)}
</FormItem>
</div>
<div className="inline-block">
<FormItem label="Recovery (%)">
{getFieldDecorator(`recovery_percentage[${key}]`, {
rules: [
{
required: true,
message: "Please input the recovery percentage"
}
]
})(<Input type="number" step="0.000001" />)}
</FormItem>
</div>
<div className="inline-block pointer">
<span>
<Icon type="close" onClick={this.removeMOCField.bind(this, key)} />
</span>
</div>
</div>
);
}
addMOCField(event: React.MouseEvent<HTMLElement>) {
event.preventDefault();
const { mocFields } = this.state;
const MOCField = this.getMOCField(mocFields.length);
mocFields.push(MOCField);
this.setState({
mocFields
});
}
getAddMOCButton() {
return (
<div className="d-flex w-100 mt-3">
<Button
type="primary"
ghost
className="w-100"
onClick={this.addMOCField}
>
<Icon type="plus-circle" />
Add MOC
</Button>
</div>
);
}
render() {
const { mocFields } = this.state;
const mocButton = this.getAddMOCButton();
const toRender =
mocFields.length > 0 ? (
<div className="w-100 p-2 gray-background br-25">
{mocFields.map((f, index) => (
<div key={index}>{f}</div>
))}
{this.getMOCFieldFooter()}
</div>
) : (
mocButton
);
return toRender;
}
}
What could be the reason for this? What am I doing incorrectly? Currently the above component renders as follows:
If the number of fields in mocFields is zero, then a button to add new fields is rendered.
After the button is pressed, mocField is populated with the select box and input field as shown above. The key of the div is decided during the render method.
It seems that the listeners doesn't work once they are stored in the array. I've tried to inline the call to getMOCField in the render function and it works. Here is what I've changed to get it work:
class MOC extends Component {
// ...
addMOCField(event) {
event.preventDefault();
const { mocFields } = this.state;
// We only keep inside the state an array of number
// each one of them represent a section of fields.
const lastFieldId = mocFields[mocFields.length - 1] || 0;
const nextFieldId = lastFieldId + 1;
this.setState({
mocFields: mocFields.concat(nextFieldId),
});
}
removeMOCField(key, event) {
event.preventDefault();
this.setState(prevState => ({
mocFields: prevState.mocFields.filter(field => field !== key)
}));
}
render() {
const { mocFields } = this.state;
const mocButton = this.getAddMOCButton();
const toRender =
mocFields.length > 0 ? (
<div className="w-100 p-2 gray-background br-25">
{/* {mocFields.map((f, index) => (
<div key={index}>{f}</div>
))} */}
{mocFields.map(fieldIndex => (
<div key={fieldIndex}>{this.getMOCField(fieldIndex)}</div>
))}
{this.getMOCFieldFooter()}
</div>
) : (
mocButton
);
return toRender;
}
}
I'm trying to access a parent method from a child to show a modal on screen and I'm getting the error: This.props.toggleModal is not a function. I'm passing the method down to the child so it can be called and using the correct state (I think). The button does call it's own method which in turn calls the parent. The modal component sits inside App.js.
App.js
class App extends Component {
constructor() {
super()
this.state = {
isOpen: false
}
}
toggleModal = () => {
this.setState({
isOpen: !this.state.isOpen
});
console.log('Open');
}
render() {
return (
<div className="App">
<Modal toggleModal={this.toggleModal} show={this.state.isOpen}
onClose={this.toggleModal}>
Here's some content for the modal
</Modal>
<div className="container">
<Header/>
<main>
<Route path="/users"
children={({ match, ...rest }) => (
<TransitionGroup component={firstChild}>
{match && <UserList {...rest} />}
</TransitionGroup>
)}/>
...
</main>
<Footer />
</div>
</div>
);
}
}
SearchBar.js - (located inside the user page)
class SearchBar extends Component {
constructor(props) {
super(props)
this.state = {
type: this.props.type,
value: ''
};
}
componentWillReceiveProps(nextProps) {
if (nextProps.type !== this.props.type) {
this.setState({ type: nextProps.type });
}
};
handleClick = (e) => {
e.preventDefault();
console.log("Clicked!!!");
this.props.toggleModal();
};
handleChange = e => {
console.log(this.state.type);
this.setState({ value: e.target.value });
};
render () {
const isUser = this.state.type;
let rightContent = null;
if (isUser === "tour" || isUser === "venue") {
rightContent =
<div className="column">
<div className="float-right"><button className="add-new" onClick={this.handleClick}>Add New</button></div>
</div>
} else {
rightContent =
<div className="column">
<div className="float-right">
<div className="results-block">
<b>0</b>/<small>292</small>
</div>
</div>
</div>
}
return (
<div className="row main-search">
<div className="column">
<form action="">
<fieldset>
<label htmlFor="search">
<input type="text"
placeholder="Start typing..."
id="search-box"
onChange={this.handleChange}
value={this.state.value} />
</label>
</fieldset>
</form>
</div>
{rightContent}
</div>
)
}
}
export default SearchBar;
Check IF you getting toggleModal as props in your User Page Compoenent. If yes then pass it explicitly like to SearchBar
<SearchBar toggleModal = {this.props.toggleModal } /> // plus your rest of the props
You have to bind toggleModal with this in constructor so that use it as this.toggleModal.
EX.
this.toggleModal = this.toggleModal.bind(this);
check this ReactJs doc for more info.
https://reactjs.org/docs/handling-events.html
I have one main component as follows :
render() {
const language = this.props.language.default.portal;
return (
<div>
<div className="searchLeft noPadding col-xl-2 col-lg-2 col-md-2 col-sm-3 col-xs-5">
<Price language={language} actionFilters={this.props.actionFilters} allCarsInTheList={this.props.carsToShow}/>
</div>
<div className="contentRight noPadding col-xl-10 col-lg-10 col-md-10 col-sm-9 col-xs-7">
<div className="filterBar">
<SmallFilters language={language} filters={this.props.filters} allCarsInTheList={this.props.carsToShow} actionFilters={this.props.actionFilters}/>
</div>
</div>
</div>
);
}
My price component is as follows :
export default class PriceRangeFilter extends React.Component {
constructor(props) {
super(props);
this.state = {
range: {
low: _.min(this.props.allCarsInTheList.map (i => i.price)),
high: _.max(this.props.allCarsInTheList.map (i => i.price)),
active: false
}
};
}
handleFilter(){
if(this.state.range.active){
this.props.actionFilters.addPriceRangeFilter(this.state.range);
}else{
this.props.actionFilters.removePriceRangeFilter();
}
}
changeFilter(range) {
this.setState({range: range}, this.handleFilter);
}
deActivate(event) {
event.preventDefault();
let n_range = this.state.range;
n_range.active = false;
this.changeFilter(n_range);
}
renderSmall() {
return (
<div key={this.props.key} className="filter">
{this.props.title} <Link to="" onClick={this.deActivate.bind(this)}><FontAwesome name="times" className="portalFaRedIcon"/></Link>
</div>
);
}
render(){
const language = this.props.language;
if(this.props.recap) return this.renderSmall();
console.log(this.state.range);
return (
<div>
<div className="priceTitle">{language.price}</div>
<SliderRange language={language}
range={this.state.range}
min={_.min(this.props.allCarsInTheList.map (i => i.price))}
max={_.max(this.props.allCarsInTheList.map (i => i.price))}
step={data.configuration.PRICE_RANGE_STEP}
sign="€"
type="price"
onChange={this.changeFilter.bind(this)} />
</div>
);
}
}
And my SmallFilters component is as follows :
import PriceFilter from './price';
class filters extends React.Component {
checkFilter(name, filters){
return filters.some(f => name == f.name);
}
showFilter(filters){
if(this.checkFilter(filter_names.priceRange, filters)){
return <PriceFilter recap={this.checkFilter(filter_names.priceRange, filters)} title="Price" allCarsInTheList={this.props.allCarsInTheList} actionFilters={this.props.actionFilters}/>
}
}
render(){
const language = this.props.language;
const filters = this.props.filters;
return (
<div className="filters noPadding col-xl-8 col-lg-6 col-md-6 col-sm-5 col-xs-12">
<ReactCSSTransitionGroup transitionName="example" transitionAppear={true} transitionAppearTimeout={500} transitionEnterTimeout={500} transitionLeaveTimeout={500}>
{this.showFilter(filters)}
</ReactCSSTransitionGroup>
</div>
);
}
}
The problem is in the SmallFilters component. I include there the same Price component as in the Search component. Then, in the price component I return renderSmall function if this.props.recap is true.
When I click on the link inside renderSmall to deactivate the filter it should update the state. But the state isn't changed. this.state.range.active stays true.
Any advice?
UPDATE
SliderRange component code is as follows :
import React, {PropTypes} from 'react';
import {formatNumber} from './formatNumber';
export default class SliderRange extends React.Component {
constructor(props) {
super(props);
this.state = this.getStateFromProps(this.props);
}
componentWillReceiveProps(newProps){
this.setState(this.getStateFromProps(newProps));
}
getStateFromProps(props) {
return {
low: props.range.low,
high: props.range.high,
active: props.range.active
};
}
numberWithSpace(number) {
return (this.props.type == "year") ? number : formatNumber(number);
}
handleChange(low, high, active) {
let n_active = active;
if(low!=this.state.low) n_active = true;
if(high!=this.state.high) n_active = true;
if(low == this.props.min && high == this.props.max) n_active = false;
const result = {
low: low,
high: high,
active: n_active
};
this.props.onChange(result);
}
handleActive(event) {
const checkbox = event.target.checked;
let low = this.state.low;
let high = this.state.high;
if(checkbox && this.state.low == this.props.min && this.state.high == this.props.max) {
low = this.props.min + this.props.step;
high = this.props.max - this.props.step;
}else{
low = this.props.min;
high = this.props.max;
}
this.handleChange(low, high, checkbox);
}
handleLow(event) {
if(parseInt(event.target.value) < parseInt(this.state.high)){
this.handleChange(event.target.value, this.state.high, this.state.active);
}
}
handleHigh(event) {
if(parseInt(event.target.value) > parseInt(this.state.low)) {
this.handleChange(this.state.low, event.target.value, this.state.active);
}
}
render() {
const sign = this.props.sign;
const min = this.props.min;
const max = this.props.max;
const step = this.props.step;
const low = this.state.low;
const high = this.state.high;
const active = this.state.active;
return (
<div>
<div className="rangeValues">Range : {this.numberWithSpace(low)} {sign} - {this.numberWithSpace(high)} {sign}</div>
<section className="range-slider">
<input type="checkbox" checked={active} onChange={this.handleActive.bind(this)}/>
<input type="range" name="first" value={low} min={min} max={max} step={step} onChange={this.handleLow.bind(this)} className="firstRange"/>
<input type="range" name="second" value={high} min={min} max={max} step={step} onChange={this.handleHigh.bind(this)} className="secondRange"/>
<div className="minValue">{this.numberWithSpace(min)} {sign}</div>
<div className="maxValue">{this.numberWithSpace(max)} {sign}</div>
</section>
</div>
);
}
}
SliderRange.propTypes = {
language: PropTypes.object.isRequired,
range: PropTypes.object.isRequired,
min: PropTypes.number.isRequired,
max: PropTypes.number.isRequired,
step: PropTypes.number.isRequired,
onChange: PropTypes.func.isRequired
};
You are changing a nested property. Try creating a new object using Object.assign() as follows:
deActivate(event) {
event.preventDefault();
let n_range = Object.assign({}, this.state.range);
n_range.active = false;
this.changeFilter(n_range);
}