Nouislider reactjs set value - reactjs

https://www.npmjs.com/package/nouislider-react
can't insert value into slider
class KeyboardSlider extends React.Component {
state = { ref: null };
changeByRef = () => {
const { ref } = this.state;
if (ref && ref.noUiSlider) {
ref.noUiSlider.set(20);
}
};
render() {
return (
<div>
<button onClick={this.changeByRef}>Change with ref</button>
<Nouislider
instanceRef={instance => {
if (instance && !ref) {
this.setState({ ref: instance });
}
}}
start={0}
range={{
min: 0,
max: 100
}}
/>
</div>
);
}
}
this code does not work gives an error
Line 665: 'ref' is not defined no-undef
....................................................................................................

try this code i just refactor you are using the ref in wrong way.
you can also use input and change the value by updating the start prop on Slider.
class KeyboardSlider extends React.Component {
constructor(props){
super(props);
this.ref = React.CreateRef();
}
changeByRef = () => {
if (this.ref && this.ref.noUiSlider) {
this.ref.noUiSlider.set(20);
}
};
render() {
return (
<div>
<button onClick={this.changeByRef}>Change with ref</button>
<Nouislider
instanceRef={instance => {
if (instance && !ref) {
this.setState({ ref: instance });
}
}}
start={0}
range={{
min: 0,
max: 100
}}
/>
</div>
);
}

Related

React this.setState function gives error when try to set new state value

When I try to update state of component with this.setState function (with or without callback) it gives following warning followed by an error as shown below.
Warning: An update (setState, replaceState, or forceUpdate) was scheduled from inside an update function. Update functions should be pure, with zero side-effects. Consider using componentDidUpdate or a callback.
Uncaught TypeError: itemValue.toLowerCase is not a function
import React from 'react';
import ReactAutocomplete from 'react-autocomplete';
export default class AddMedicine extends React.Component {
constructor (props) {
super(props)
this.state = {
autocompleteData: props.list,
bid: '',
formId: '',
formsOfBrand: []
};
this.renderBrandItem = this.renderBrandItem.bind(this);
this.onChangeBrand = this.onChangeBrand.bind(this);
this.onSelectBrand = this.onSelectBrand.bind(this);
this._getFormsByBID = this._getFormsByBID.bind(this);
this.renderFormItem = this.renderFormItem.bind(this);
this.onChangeForm = this.onChangeForm.bind(this);
this.onSelectForm = this.onSelectForm.bind(this);
}
renderBrandItem(item, highlighted) {
return <div
key={item.bid}
style={{ backgroundColor: highlighted ? '#eee' : 'transparent'}}
>
{item.brand_name}
</div>
}
onChangeBrand(e) { this.setState({
bid: e.target.value,
formsOfBrand : ['dd', 'dfsd']
})
}
onSelectBrand(bid) {
this.setState( (prevState) => {
let newState = {...prevState};
newState.bid = bid;
newState.formsOfBrand = this._getFormsByBID(bid);
console.log(newState);
return newState;
});
}
componentDidUpdate() {}
_getFormsByBID(id){
let brand = this.state.autocompleteData.filter(brand => {
console.log(brand); console.log(id);
return (brand.bid == id)? true : false; }
);
brand = brand[0];
console.log(brand);
return brand.forms;
}
renderFormItem(item, highlighted) {
return <div
key={Object.keys(item)[0]}
style={{ backgroundColor: highlighted ? '#eee' : 'transparent'}}
>
{item[Object.keys(item)[0]]}
</div>
}
onChangeForm(e) { this.setState({ formId: e.target.value }) }
onSelectForm(formId) { this.setState({ formId: formId }) }
render() {
return (
<React.Fragment>
<ReactAutocomplete
items={this.state.autocompleteData}
getItemValue={item => item.bid}
renderItem={this.renderBrandItem}
value={this.state.bid}
onSelect={this.onSelectBrand}
/>
<select>
{this.state.formsOfBrand.forEach((form) =>
<option value={Object.keys(form)[0]}>{form[Object.keys(form)[0]]}</option>
)}
</select>
</React.Fragment>
)
}
}

React function - is not defined no-undef

I get the following error when trying to compile my app 'handleProgress' is not defined no-undef.
I'm having trouble tracking down why handleProgress is not defined.
Here is the main react component
class App extends Component {
constructor(props) {
super(props);
this.state = {
progressValue: 0,
};
this.handleProgress = this.handleProgress.bind(this);
}
render() {
const { questions } = this.props;
const { progressValue } = this.state;
const groupByList = groupBy(questions.questions, 'type');
const objectToArray = Object.entries(groupByList);
handleProgress = () => {
console.log('hello');
};
return (
<>
<Progress value={progressValue} />
<div>
<ul>
{questionListItem && questionListItem.length > 0 ?
(
<Wizard
onChange={this.handleProgress}
initialValues={{ employed: true }}
onSubmit={() => {
window.alert('Hello');
}}
>
{questionListItem}
</Wizard>
) : null
}
</ul>
</div>
</>
);
}
}
Your render method is wrong it should not contain the handlePress inside:
You are calling handlePress on this so you should keep it in the class.
class App extends Component {
constructor(props) {
super(props);
this.state = {
progressValue: 0,
};
this.handleProgress = this.handleProgress.bind(this);
}
handleProgress = () => {
console.log('hello');
};
render() {
const { questions } = this.props;
const { progressValue } = this.state;
const groupByList = groupBy(questions.questions, 'type');
const objectToArray = Object.entries(groupByList);
return (
<>
<Progress value={progressValue} />
<div>
<ul>
{questionListItem && questionListItem.length > 0 ?
(
<Wizard
onChange={this.handleProgress}
initialValues={{ employed: true }}
onSubmit={() => {
window.alert('Hello');
}}
>
{questionListItem}
</Wizard>
) : null
}
</ul>
</div>
</>
);
}
}
If you are using handleProgress inside render you have to define it follows.
const handleProgress = () => {
console.log('hello');
};
if it is outside render and inside component then use as follows:
handleProgress = () => {
console.log('hello');
};
If you are using arrow function no need to bind the function in constructor it will automatically bind this scope.
handleProgress should not be in the render function, Please keep functions in you component itself, also if you are using ES6 arrow function syntax, you no need to bind it on your constructor.
Please refer the below code block.
class App extends Component {
constructor(props) {
super(props);
this.state = {
progressValue: 0,
};
// no need to use bind in the constructor while using ES6 arrow function.
// this.handleProgress = this.handleProgress.bind(this);
}
// move ES6 arrow function here.
handleProgress = () => {
console.log('hello');
};
render() {
const { questions } = this.props;
const { progressValue } = this.state;
const groupByList = groupBy(questions.questions, 'type');
const objectToArray = Object.entries(groupByList);
return (
<>
<Progress value={progressValue} />
<div>
<ul>
{questionListItem && questionListItem.length > 0 ?
(
<Wizard
onChange={this.handleProgress}
initialValues={{ employed: true }}
onSubmit={() => {
window.alert('Hello');
}}
>
{questionListItem}
</Wizard>
) : null
}
</ul>
</div>
</>
);
}
}
Try this one, I have check it on react version 16.8.6
We don't need to bind in new version using arrow head functions. Here is the full implementation of binding argument method and non argument method.
import React, { Component } from "react";
class Counter extends Component {
state = {
count: 0
};
constructor() {
super();
}
render() {
return (
<div>
<button onClick={this.updateCounter}>NoArgCounter</button>
<button onClick={() => this.updateCounterByArg(this.state.count)}>ArgCounter</button>
<span>{this.state.count}</span>
</div>
);
}
updateCounter = () => {
let { count } = this.state;
this.setState({ count: ++count });
};
updateCounterByArg = counter => {
this.setState({ count: ++counter });
};
}
export default Counter;

React passing props to components

I am trying to pass in props to a component which works while using componentWillReceiveProps, but once the counter is done it calls clearInterval(this.intervalId);However once I change the input again the counter does not get initiated again. How can i pass the updated props back to the component?
Component code;
class Stopwatch extends Component {
constructor(props) {
super(props);
this.state = {
currentCount: this.props.counter,
hours: 0,
minutes: 0,
seconds: 0
}
}
componentWillMount() {
this.timer(this.props.counter);
}
timer() {
this.setState({
currentCount: this.state.currentCount - 1
})
const seconds = Math.floor(this.state.currentCount % 60);
const minutes = Math.floor((this.state.currentCount/60) % 60);
const hours = Math.floor((this.state.currentCount/3600) % 3600);
this.setState({hours, minutes, seconds});
if (this.state.currentCount < 1) {
clearInterval(this.intervalId);
}
}
componentDidMount() {
this.intervalId = setInterval(this.timer.bind(this), 1000);
}
leading0(num) {
return num < 10 ? '0' + num : num;
}
componentWillReceiveProps(nextProps){
if(nextProps.counter !== this.props.counter){
this.setState ({currentCount: nextProps.counter})
}
}
render() {
return (
<div>
<div>Hours {this.leading0(this.state.hours)}</div>
<div>Minutes {this.leading0(this.state.minutes)}</div>
<div>Seconds {this.leading0(this.state.seconds)}</div>
</div>
)
Main Code;
class App extends Component {
constructor(props) {
super(props);
this.state = {
deadline: 'December 25, 2018',
newDeadline: '',
counter: 75,
newCounter: ''
};
}
changeDeadline() {
this.setState({deadline: this.state.newDeadline});
}
changeNumber(e) {
this.setState({counter: this.state.newCounter});
}
render() {
return (
<div className='App'>
<div className='App-title'>Countdown to {this.state.deadline}</div>
<Clock
deadline={this.state.deadline}
/>
<Form inline>
<FormControl
className="Deadline-input"
placeholder='New Date'
onChange={event => this.setState({newDeadline: event.target.value})}
/>
<Button onClick={() => this.changeDeadline()}>Submit</Button>
</Form>
<div>Stopwatch From { this.state.counter } Seconds</div>
<Stopwatch
counter={this.state.counter}
/>
<Form inline>
<FormControl
className="Deadline-input"
placeholder='New Number'
onChange={event => this.setState({newCounter: event.target.value})}
/>
<Button onClick={() => this.changeNumber()}>Submit</Button>
</Form>
</div>
)
}
Thanks in Advance
componentDidMount function calls once, if you want to reset counter on props change, you should do it in componentWillReceiveProps function
class Stopwatch extends Component {
// ...
resetInterval() {
if (this.intervalId) {
clearInterval(this.intervalId);
this.intervalId = null;
}
this.intervalId = setInterval(this.timer.bind(this), 1000);
}
componentWillReceiveProps(nextProps){
if(nextProps.counter !== this.props.counter){
this.setState ({currentCount: nextProps.counter})
// reset interval
this.resetInterval()
}
}
//...
}

Showing two different components based on return value in react js

I have search function where on entering text it returns the object from an array(json data) and based on the condition (whether it as an object or not) I need to show two different components ie. the list with matched fields and "No matched results found" component.
class Search extends React.Component {
constructor(props) {
super(props);
this.state = {
searchTextData: '',
isSearchText: false,
isSearchOpen: false,
placeholderText:'Search Content',
filteredMockData: [],
dataArray: []
};
}
handleSearchChange = (event, newVal) => {
this.setState({ searchTextData: newVal })
if (newVal == '') {
this.setState({ clearsearch: true });
this.setState({
filteredMockData: []
});
this.props.onDisplayCloseIcon(true);
} else {
this.props.onDisplayCloseIcon(false);
searchData.searchResults.forEach((item, index, array) => {
this.state.dataArray.push(item);
});
this.setState({ filteredMockData: this.state.dataArray });
}
}
clearInput = () => {
this.setState({ searchTextData: '' })
}
isSearchText = () => {
this.setState({ isSearchText: !this.state.isSearchText });
}
onSearchClick = () => {
this.setState({ isSearchOpen: !this.state.isSearchOpen });
this.setState({ searchTextData: '' });
this.props.onDisplayCloseIcon(true);
}
renderSearchData = () => {
const SearchDatasRender = this.state.dataArray.map((key) => {
const SearchDataRender = key.matchedFields.pagetitle;
return (<ResultComponent results={ SearchDataRender } /> );
})
return SearchDatasRender;
}
renderUndefined = () => {
return ( <div className = "search_no_results" >
<p> No Recent Searches found. </p>
<p> You can search by word or phrase, glossary term, chapter or section.</p>
</div>
);
}
render() {
return ( <span>
<SearchIcon searchClick = { this.onSearchClick } />
{this.state.isSearchOpen &&
<div className = 'SearchinputBar' >
<input
placeholder={this.state.placeholderText}
className= 'SearchInputContent'
value = { this.state.searchTextData}
onChange = { this.handleSearchChange }
/>
</div>
}
{this.state.searchTextData !== '' && this.state.isSearchOpen &&
<span className='clearText'>
<ClearIcon className='clearIcon' clearClick = { this.clearInput }/>
</span>
}
{this.state.searchTextData !== '' && this.state.isSearchOpen &&
<div className="SearchContainerWrapper">
<div className = "arrow-up"> </div>
<div className = 'search_result_Container' >
<div className = "search_results_title" > <span> Chapters </span><hr></hr> </div>
<div className="search_show_text" >
<ul className ="SearchScrollbar">
{this.state.filteredMockData.length ? this.renderSearchData() : this.renderUndefined() }
</ul>
</div>
</div>
</div>}
</span>
);
}
}
Search.propTypes = {
intl: intlShape.isRequired,
onSearchClick: PropTypes.func,
isSearchBarOpen: PropTypes.func,
clearInput: PropTypes.func,
isSearchText: PropTypes.func
};
export default injectIntl(Search);
Search is my parent component and based on the matched values I need to show a resultComponent like
class ResultComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
};
}
render(){
console.log(this.props.renderSearchData(),'Helloooo')
return(<p>{this.props.renderSearchData()}</p>)
}
}
ResultComponent.propTypes = {
results: PropTypes.string.isRequired
};
I'm getting an error "renderSearchData is not an function".I'm new to react and Hope someone can help.
The only prop passed to ResultComponent component is results
So in ResultComponent Component Replace
this.props.renderSearchData()
With
this.props.results

redux-form always returns same values for Multiselect react-widget

I am trying to use redux-form with react-widget Multiselect this example:
var Multiselect = ReactWidgets.Multiselect
, people = listOfPeople();
var Example = React.createClass({
getInitialState() {
return { value: people.slice(0,2) };
},
_create(name){
var tag = { name, id: people.length + 1 }
var value = this.state.value.concat(tag)
// add new tag to the data list
people.push(tag)
//add new tag to the list of values
this.setState({ value })
},
render(){
// create a tag object
return (
<Multiselect data={people}
value={this.state.value}
textField="name"
onCreate={this._create}
onChange={value => this.setState({ value })}/>
)
}
});
ReactDOM.render(<Example/>, mountNode);
Below is a code snippet for a parent component which makes usage of redux-form (EditVideo component) component (please look at the comments in onSubmit method):
class VideoEdit extends React.Component {
constructor(props) {
super(props);
}
onSubmit = (values) => {
console.log(values.categories) // always returns initialValues for categories, new values not adding
}
render() {
const { loading, videoEdit, categories } = this.props;
if (loading) {
return (
<div>{ /* loading... */}</div>
);
} else {
return (
<div>
<h2>Edit: {videoEdit.title}</h2>
<EditVideo
onSubmit={this.onSubmit}
initialValues={videoEdit}
categories={categories}
/>
</div>
);
}
}
}
And here is a code snippet of redux-form component with react-widget Multiselect component:
class CategoryWidget extends React.Component {
constructor(props) {
super(props);
this.state = {
value: this.props.defValue,
extData: this.props.data
}
this._create = this._create.bind(this);
}
_create(name) {
var tag = { name, id: this.state.extData.length + 100 + 1 }
var value = this.state.value.concat(tag)
var extData = this.state.extData.concat(tag)
this.setState({
extData,
value
})
}
render() {
return (
<Multiselect
{...this.props.input}
data={this.state.extData}
onBlur={() => this.props.input.onBlur()}
value={this.state.value || []}
valueField="id"
textField="name"
onCreate={this._create}
onChange={value => this.setState({ value })}
/>
)
}
}
const EditVideoForm = (props) => {
const { handleSubmit, submitting, onSubmit, categories, initialValues, defBook } = props;
return (
<Form name="ytvideo" onSubmit={handleSubmit(onSubmit)}>
<div>
<Field
name="categories"
component={CategoryWidget}
data={categories}
defValue={initialValues.categories}
/>
</div>
<br />
<Button color="primary" type="submit" disabled={submitting}>
Submit
</Button>
</Form>
);
};
export default reduxForm({
form: 'videoEdit',
enableReinitialize: true
})(EditVideoForm);
The Multiselect widget works as expected, yet the form on submit always returns the same initial values for categories.
I believe the problem lays in the fact that CategoryWidget is a class base component? If so, what is a way to make it work?
Here is what I have done for my Multiselect at the end:
class CategoryWidget extends React.Component {
constructor(props) {
super(props);
this.state = {
value: this.props.defValue,
extData: this.props.data
}
this._create = this._create.bind(this);
}
_create(name) {
var tag = { name, id: this.state.extData.length + 100 + 1 }
var value = this.state.value.concat(tag)
var extData = this.state.extData.concat(tag)
this.setState({
extData,
value
})
}
componentDidUpdate() {
let { onChange } = this.props.input
onChange(this.state.value)
}
handleOnChange(value) {
this.setState({ value })
}
render() {
const input = this.props.input
return (
<Multiselect
{...input}
data={this.state.extData}
onBlur={() => input.onBlur()}
value={this.state.value || []}
valueField="id"
textField="name"
onCreate={this._create}
onChange={value => this.handleOnChange(value)}
/>
)
}
}

Resources