I'm using React.JS for building a range input slider.The value of min , max and value have been set by {this.renderMinTotal()} and {this.renderMaxTotal()}.The main problem is that when I try to toggle it it does not move at all.I know that I should use onChange handler but I do not know what to write.
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
data: [],
library: null,
};
}
componentDidMount() {
fetch("/json.bc", {
method: "get"
})
.then(response => response.text())
.then(text => {
let Maindata = JSON.parse(text.replace(/\'/g, '"'));
this.setState(
state => ({
...state,
data: Maindata
}),
() => {
this.reorganiseLibrary();
}
);
})
.catch(error => console.error(error));
}
reorganiseLibrary = () => {
const { data } = this.state;
let library = data;
library = _.chunk(library);
this.setState({
library,
});
};
handlePerPage = evt =>
this.setState(
{
perPage: evt.target.value
},
() => this.reorganiseLibrary()
);
renderMinTotal = () => {
const { library } = this.state;
if (!library || (library && library.length === 0)) {
return "";
}
return library.reduce((acc, lib) => {
const libMin = Math.min(...lib.map(item => item.totalCom));
return acc === undefined ? libMin : libMin < acc ? libMin : acc;
}, undefined);
};
renderMaxTotal = () => {
const { library } = this.state;
if (!library || (library && library.length === 0)) {
return "";
}
return library.reduce((acc, lib) => {
const libMax = Math.max(...lib.map(item => item.totalCom));
return libMax > acc ? libMax : acc;
}, 0);
};
handlerChange = evt =>{
let value = evt.target.value
///what should be written here///////
}
render() {
const { library } = this.state;
return (
<div>
<div>
<input
type="range"
min={this.renderMinTotal()}
max={this.renderMaxTotal()}
value={this.renderMaxTotal()}
step="1000"
className="multirange"
onChange={this.handlerChange}
/>
</div>
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById('Result'))
i don't see reason to load value of your range-input from
( this.renderMaxTotal() )
try just leaving value blank, later on try f.e.
onChange={(event)=>{console.log(event.target.value)}}
Related
// App.js - WEB
/* eslint-disable no-undef */
import { hot } from 'react-hot-loader/root';
import React, { Component } from "react";
import { View, Platform, Dimensions, Linking, Text } from "react-native";
import { Routes } from "react-router-dom";
import { ModalContainer } from "react-router-modal";
import IdleTimer from "react-idle-timer";
import {
BroadcastChannel
} from 'broadcast-channel';
import { withRouter } from './utils/withRouterComponent';
const routeMap = {
...CommonRouteMap,
};
class App extends Component {
constructor(props) {
super(props);
this.state = {
backgroundColor: "#F36414",
openmodel: false,
bootboxtext: "",
modalopenhide: false,
measure: getMeasure(this.getWidth()),
workingtime: true,
userIdle: false,
maintainanceText: APP.MAINTAINANCE_TIME,
linearColors: linearColors(),
isDuplicate: false
};
this.handleWindowPerformanceEvents();
// Store the previous pathname and search strings
this.currentPathname = null;
this.currentSearch = null;
this.workingTime = dayjs(new Date()).format("HH");
}
changeBackground = (color) => {
this.setState({ backgroundColor: color });
};
handleLayout = ({ nativeEvent }) => {
const { width } = nativeEvent.layout;
const measure = getMeasure(width);
this.setState(() => ({ measure }));
};
getWidth = () => {
const { width } = Dimensions.get("window");
return width;
};
handleWindowPerformanceEvents = async () => {
let ExternalFlag;
if (Platform.OS === "web") {
ExternalFlag = sessionStorage.getItem("ExternalFlag");
} else {
ExternalFlag = await AsyncStorage.getItem("ExternalFlag");
}
let parts = window.location.pathname.split("/");
let path = parts[parts.length - 1];
if (window.performance) {
if (
performance.navigation.type === 0 &&
!window.location.pathname != "404Page"
) {
localStorage.clear();
} else if (!window.location.pathname != "404Page") {
localStorage.clear();
const pathName = window.location.pathname;
const domainName = window.location.origin;
let updatedPath = pathName.substr(0, pathName.lastIndexOf("/"));
if (paths.includes(updatedPath)) {
if (ExternalFlag == 'false') {
window.location.href = `${domainName}${updatedPath}`;
}
return;
} else {
if (ExternalFlag == 'false') {
window.location.href = `${window.location.origin}/servicing/index.html`;
}
}
}
}
};
async componentDidMount() {
const bc = new BroadcastChannel("MY-Project");
bc.onmessage = (event) => {
if (event === "newTab") {
bc.postMessage(`duplicateTab`);
this.setState({ isDuplicate: false })
}
if (event === `duplicateTab`) {
bc.close()
}
};
bc.postMessage('newTab');
this.myContext = {
...this.myContext,
isSupported: await this.isSupportedForVKYC(),
};
const windowValues = window.location;
this.navigateOptions();
if (
windowValues.pathname.includes("product") &&
windowValues.search != ""
) {
fetchUrl(windowValues, this.props);
}
this.setState({
workingtime: true,
});
this.interval = setInterval(() => this.timer(windowValues), 5000);
let machine = null;
if (Platform.OS === 'web') {
machine = sessionStorage.getItem('machine');
}
if (machine) {
this.setState({ machine: true })
}
}
componentWillUnmount() {
clearInterval(this.interval);
}
timer = (windowValues) => {
if (
windowValues.hostname != "localhost" &&
this.state.workingtime &&
!(this.workingTime >= 6 && this.workingTime < 23)
) {
this.setState({
workingtime: true,
});
this.interval = setInterval(() => this.timer(windowValues), 5000);
}
};
navigateOptions() {
const { history } = this.props;
if (
window.location.pathname ===
`${"/" + injectUrlPaths(window.location).path + "/"}`
) {
history.push(`${"/" + injectUrlPaths(window.location).path + ""}`);
}
}
refresh() {
let clear = [
"time",
"product_name",
"payment_gateway",
"stopwatch",
"credit_opted",
"flow",
"easyPay",
"token",
];
clear.forEach((item) => {
sessionStorage.removeItem(item);
});
}
handleKeyPress = (event) => {
if (this.state.userIdle && event.keyCode === 9) {
event.preventDefault();
}
};
closebootbox = () => {
if (this.state.userIdle) {
this.refresh();
window.removeEventListener("keydown", this.handleKeyPress);
Linking.openURL(window.location.origin);
} else {
this.setState({
openmodel: false,
modalopenhide: false,
});
}
};
onIdle = async () => {
const pathName = window.location.pathname;
window.addEventListener('keydown', this.handleKeyPress);
let ExternalFlag = (Platform.OS === "web") ? sessionStorage.getItem("ExternalFlag") : await AsyncStorage.getItem("ExternalFlag");
const { history } = this.props;
let newProps = this.props.location.state;
newProps = { ...newProps, idle: true };
let redirectPath = "/servicing/index.html";
let parts = window.location.pathname.split("/");
let path = parts[parts.length - 1];
if (ExternalFlag) {
history.push({
pathname: '/servicing/redirectHome',
state: newProps
});
} else {
let machine = null;
if (Platform.OS === 'web') {
machine = sessionStorage.getItem('machine');
}
if (machine) {
window.location.href = `http://localhost:9309/SendStatus?CurrentStatus=Timeout`;
} else {
history.push({
pathname: redirectPath,
state: newProps
});
}
}
};
setTimeout = data => {
if (data.otptimer) {
this.idleTimer.pause();
} else {
this.idleTimer.resume();
}
};
clearStorage = (data) => {
data.map((item) => {
sessionStorage.removeItem(item);
});
};
render() {
const ua = window.navigator.userAgent;
return (
!this.state.isDuplicate ?
<CacheBuster enableCaching>
{({ loading, isLatestVersion, refreshCacheAndReload }) => {
if (loading) return null;
if (!loading && !isLatestVersion) {
refreshCacheAndReload();
}
return (
browserSupport(ua) && (
<LinearGradient {...this.state.linearColors}>
<IdleTimer
ref={(ref) => {
this.idleTimer = ref;
}}
element={document}
onIdle={this.onIdle}
debounce={APP.DEBOUNCE}
timeout={APP.IDLE_TIMEOUT}
/>
<View onLayout={this.handleLayout} style={styles.container}>
<script>
window.onpopstate = function() {this.props.history.go(1)};
</script>
{this.state.workingtime ? (
<AppProvider value={{ ...this.myContext, ...this.state }}>
<View style={styles.rootStyle}>
<CustomBootbox
{...this.props}
measure={this.state.measure}
bootboxtext={this.state.bootboxtext}
bootboxmodal={this.state.openmodel}
closebootbox={this.closebootbox}
hideBlackout
/>
<Routes>
{WebRoutesGenerator(
{ routeMap },
this.changeBackground
)}
</Routes>
<ModalContainer />
</View>
</AppProvider>
) : (
<AvailableTimeError
maintainanceText={this.state.maintainanceText}
/>
)}
</View>
</LinearGradient>
)
);
}}
</CacheBuster> : <View style={{ height: Dimensions.get("window").height, }}>
<View >
<Text>Previous session is already open...!</Text>
<Text><br></br> Please close the window and try again </Text>
</View>
</View>
);
}
}
export default hot((withRouter((App))))
I have a react native project and it was running in the older version of React, React Dom and rest. After updating the application to match the latest version, I am getting the above error and I couldn't find a proper solution for it.
Initially I searched withRouter imports and uses, and then created a custom hook of withRouter. Still the error persists.
import {
useLocation,
useNavigate,
useParams
} from "react-router-dom";
export function withRouter(Component) {
function ComponentWithRouterProp(props) {
let location = useLocation();
let navigate = useNavigate();
let params = useParams();
return (
<Component
{...props}
router={{ location, navigate, params }}
/>
);
}
return ComponentWithRouterProp;
}
This issue is likely surfacing as you might be using --legacy-peer-deps flag when installing node_modules. Now Remove node_modules, and just try to fix code after doing npm install. have a nice day.
I'm trying to add item to the cart. If it is in cart, I want to replace this item with updated count and total accordingly, but I don't want to affect to other items. If it is not in cart I add it (logic of if statement). How to implement logic of else statement?
class ProductProvider extends Component {
constructor(props) {
super(props);
this.state = {
cart: [],
modalOpen: false,
modalProduct: {},
cartTotal: 0,
};
}
addToCart = (product) => {
const index = this.state.cart.findIndex((item) => item.id === product.id);
if (index === -1) {
const tempProduct = { ...product };
tempProduct.inCart = true;
tempProduct.count = 1;
const price = product.prices[0].amount;
tempProduct.total = price;
this.setState(
() => {
return { cart: [...this.state.cart, tempProduct] };
},
() => {
this.addTotal();
}
);
} else {
// solution must be here
}
};
addTotal = () => {
let total = 0;
this.state.cart.map((item) => (total += item.total));
this.setState(() => {
return {
cartTotal: parseFloat(total.toFixed(2)),
};
});
};
}
Seems like this approach, I'm currently trying to apply in other component works well. I need to test it and adapt for previous case.
constructor(props) {
super(props);
this.state = {
readMore: false,
activeID: null,
activeAtt: null,
selectedAttributes: [],
};
}
setAttributes = (name, value) => {
const index = this.state.selectedAttributes.findIndex(
(item) => item.name === name
);
if (index === -1) {
const newAttribute = { name, value };
this.setState(() => {
return {
selectedAttributes: [...this.state.selectedAttributes, newAttribute],
};
});
} else {
const tempAttributes = [...this.state.selectedAttributes];
const selectedAttribute = tempAttributes.find(
(attribute) => attribute.name === name
);
selectedAttribute.value = value;
this.setState(() => {
return { selectedAttributes: [...tempAttributes] };
});
}
else {
const tempCart = [...this.state.cart];
const selectedItem = tempCart.find((item) => item.id === product.id);
selectedItem.selectedAttributes = attributes;
selectedItem.count = selectedItem.count + 1;
const price = product.prices[0].amount;
selectedItem.total = selectedItem.total + price;
this.setState(
() => {
return { cart: [...tempCart] };
},
() => {
this.addTotal();
}
);
}
I am trying to implement play/pause on button clicking. While icons change perfectly, my actual functionality fails to work. My code is the following.
Function that is triggered on click
onPlayHandler = () => {
let aud = new Audio(this.props.data[this.state.index].audio);
aud.play();
this.setState({
isPlaying: true
});
};
onPauseHandler = () => {
let aud = new Audio(this.props.data[this.state.index].audio);
aud.pause()
//aud.setAttribute("ref", `${this.myRef}`);
this.setState({
isPlaying: false
});
//this.refs.audio.pause();
//x.pause();
//console.log(aud)
};
Button that is clicked
<Button playAudio={ this.state.isPlaying ? this.onPauseHandler : this.onPlayHandler } isPlaying={ this.state.isPlaying } />
Button component
export default function IconLabelButtons(props) {
const classes = useStyles();
return (
<>
<Button
variant="contained"
color="primary"
size="large"
className={ classes.button }
startIcon={ props.isPlaying ? <PauseIcon /> : <PlayArrowIcon /> }
onClick={ props.playAudio }
>
{ props.isPlaying ? 'Pause' : 'Play' }
</Button>
</>
);
Updated question
Entire code
import React, { Component } from 'react';
import Card from './Card';
import Button from './Button';
import correct from '../../data/media/correct.wav';
import denied from '../../data/media/denied.mp3';
var _ = require('lodash');
class AudioContainer extends Component {
constructor (props) {
super(props);
this.state = {
images: [],
index: 0,
checkedItems: new Map(),
correct: false,
isPlaying: false
};
this.audio = React.createRef();
}
componentDidMount() {
const arrImages = this.props.data.map((item) => {
let arr = [];
arr.push(item.picture);
return arr;
});
//console.log(arrImages)
this.setState({
images: _.shuffle(arrImages.flat(Infinity))
});
}
showImages = () => {
this.state.images && this.state.images.map((image) => (
<div>
<figure class="image is-128x128">
<img src={ image.src } alt="" />
</figure>
<span>{ image.name }</span>
</div>
));
};
handleChange = (e) => {
const item = e.target.name;
const isChecked = e.target.checked;
this.setState(prevState => ({ checkedItems: prevState.checkedItems.set(item, isChecked) }));
};
onCheckHandler = (e) => {
e.preventDefault();
/* function checkTrue(item) {
return item.value === true;
}
const filteredItems = this.state.checkedItems.filter(checkTrue) */
//console.log(this.state.checkedItems.value())
let arr = [];
// eslint-disable-next-line no-unused-vars
for (let [key, value] of this.state.checkedItems) {
let obj = {
value: key,
bool: value
};
arr.push(obj);
}
//console.log(arr);
let filteredArr = arr.filter((el) => {
return el.bool === true;
});
//console.log(filteredArr);
let arrWithAnswers = [];
filteredArr.map((el) => {
return arrWithAnswers.push(el.value);
});
//console.log(arrWithAnswers);
//console.log(this.props.data[this.state.index].answers.sort());
if (_.isEqual(arrWithAnswers.sort(), this.props.data[this.state.index].answers.sort())) {
let sound = new Audio(correct);
sound.play();
this.setState({
index: this.state.index + 1, checkedItems: new Map()
});
//console.log("true");
} else {
let sound = new Audio(denied);
sound.play();
}
};
update() {
const arrImages = this.props.data.map((item) => {
let arr = [];
arr.push(item.picture);
return arr;
});
//console.log(arrImages)
this.setState({
images: _.shuffle(arrImages.flat(Infinity))
});
}
onPlayHandler = () => {
let aud = new Audio(this.props.data[this.state.index].audio);
aud.play();
this.setState({
isPlaying: true
});
};
onPauseHandler = () => {
let aud = new Audio(this.props.data[this.state.index].audio);
aud.pause()
//aud.setAttribute("ref", `${this.myRef}`);
this.setState({
isPlaying: false
});
//this.refs.audio.pause();
//x.pause();
//console.log(aud)
};
render() {
//console.log(this.props.data)
//console.log(this.state.images)
//console.log(this.state.checkedItems.size);
return (
<div>
<Button playAudio={ this.state.isPlaying ? this.onPauseHandler : this.onPlayHandler } isPlaying={ this.state.isPlaying } />
<div className="columns is-vcentered is-multiline">
{ this.state.images && this.state.images.map((image, index) => (
<div className="column is-3" key={index}>
<Card image={ image.src } clickHandler={ this.handleChange } name={ image.name } />
</div>
)) }
</div>
<button className="button is-info" disabled={ this.state.checkedItems.size <= 0 } onClick={ this.onCheckHandler }>Check</button>
</div>
);
}
}
export default AudioContainer;
Your help is appreciated, thanks.
I was able to get it the way I want to, but I am not sure if it is a good practice. So what I did is the following.
let audio = new Audio()
class AudioContainer extends Component {
constructor (props) {
super(props);
this.state = {
images: [],
index: 0,
checkedItems: new Map(),
correct: false,
isPlaying: false,
error: false
};
}
onPlayHandler = () => {
audio.src = this.props.data[this.state.index].audio
audio.play();
this.setState({
isPlaying: true
});
};
onPauseHandler = () => {
audio.src = this.props.data[this.state.index].audio
//let aud = new Audio(this.props.data[this.state.index].audio);
audio.pause();
//aud.setAttribute("ref", `${this.myRef}`);
this.setState({
isPlaying: false
});
//this.refs.audio.pause();
//x.pause();
//console.log(aud)
};
I am very suspicious of declaring variable audio at the very top. So please correct me if I am wrong.
I am trying to use the rules in the Form. Items but because of some reason it is not supporting
NOTE: The number is not supporting but that is not an issue rules feature is not supporting at all.
NOTE: I think because it is rendering a lot that is why rules are not getting applied.
Any help to solve the issue will be great.
Here is a form component Code
import React from 'react';
import { Form, Button } from 'antd';
import { component as Template } from '#ivoyant/component-template';
class InputFormComponent extends React.Component {
state = {
formData: {},
};
enableInputFocus = (State, Props) => {
const empty = {};
const isObject = x => Object(x) === x;
const diff1 = (left = {}, right = {}, rel = 'left') =>
Object.entries(left)
.map(([k, v]) =>
isObject(v) && isObject(right[k])
? [k, diff1(v, right[k], rel)]
: right[k] !== v
? [k, { [rel]: v }]
: [k, empty]
)
.reduce(
(acc, [k, v]) => (v === empty ? acc : { ...acc, [k]: v }),
empty
);
const merge = (left = {}, right = {}) =>
Object.entries(right).reduce(
(acc, [k, v]) =>
isObject(v) && isObject(left[k])
? { ...acc, [k]: merge(left[k], v) }
: { ...acc, [k]: v },
left
);
const diff = (x = {}, y = {}) =>
merge(diff1(x, y, 'left'), diff1(y, x, 'right'));
const key = Object.keys(diff(State, Props))[0];
for (const property in Props) {
if (key == property) {
Props[property].focus = true;
} else {
Props[property].focus = false;
}
}
return Props;
};
onFinish = values => {
const { formData } = this.state;
global.console.log('Success: formData :', formData);
};
getDataFromFormItem = values => {
const { formData } = this.state;
const updatedValues = this.enableInputFocus(formData, values);
this.setState({ formData: { ...formData, ...updatedValues } });
};
onFinishFailed = errorInfo => {
global.console.log('Failed:', errorInfo);
};
render() {
const { children, properties } = this.props;
const {
submitButtonText,
formClassName,
submitButtonClassNmae,
} = properties;
const { formData } = this.state;
const childComponent = React.Children.map(children, child => {
return React.cloneElement(child, {
sendDataToForm: this.getDataFromFormItem,
updateFormData: this.updateFormData,
values: { ...formData },
});
});
return (
<div>
<Form
className={formClassName && formClassName}
onFinish={this.onFinish}
onFinishFailed={this.onFinishFailed}
>
{childComponent}
<Form.Item>
<Button
type="primary"
htmlType="submit"
className={
submitButtonClassNmae && submitButtonClassNmae
}
>
{submitButtonText && submitButtonText}
</Button>
</Form.Item>
</Form>
</div>
);
}
}
export default InputFormComponent;
Below is the code for the Input field, which is a totally different component:
import React from 'react';
import { Input, Form } from 'antd';
class InputComponent extends React.Component {
state = {
formItemData: {},
};
componentDidMount() {
const { values } = this.props;
for (const property in values) {
if (values[property].focus === true) {
this[property] && this[property].focus();
}
}
/**
* Bellow code is use when we are not passing input component as a direct child of Form component
*/
if (this.props.parentProps)
for (const property in this.props.parentProps.values) {
if (this.props.parentProps.values[property].focus === true) {
this[property] && this[property].focus();
}
}
/**
* In Bellow code true condition is exected when we are not passing input component as a direct child of Form component
*/
this.props.parentProps
? this.setState({
formItemData: { ...values, ...this.props.parentProps.values },
})
: this.setState({ formItemData: { ...values } });
}
handleOnChange = event => {
const { formItemData } = this.state;
const { id, value } = event.target;
const ID = id;
const object = {};
object[ID] = {
VALUE: value,
focus: false,
};
this.setState(
{
formItemData: { ...formItemData, ...object },
},
() => {
this.props.sendDataToForm &&
this.props.sendDataToForm(this.state.formItemData);
/**
* Bellow code is use when we are not passing input component as a direct child of Form component
*/
this.props.parentProps &&
this.props.parentProps.sendDataToForm &&
this.props.parentProps.sendDataToForm(
this.state.formItemData
);
}
);
};
render() {
const { id, className } = this.props.properties;
const { values, children } = this.props;
const { formItemData } = this.state;
const { inputFieldsConfiguration } = this.props.properties;
const childComponent = React.Children.map(children, child => {
return React.cloneElement(child, {
parentProps: { ...this.props },
});
});
return (
<div>
<div className={className && className}>
{inputFieldsConfiguration &&
// eslint-disable-next-line complexity
inputFieldsConfiguration.map(data => {
return (
<div
className={data.itemAndInputClassName}
key={data.id && data.id}
>
<div className={data.labalClassName}>
{data.label && data.label}
</div>
<Form.Item
key={data.id}
hasFeedback
name={data.id}
help={data.help && data.help}
className={
data.formItemClassName &&
data.formItemClassName
}
rules={[
{
type: "url",
}
]}
>
<Input
ref={input => {
this[data.id] = input;
}}
placeholder={
data.placeholder &&
data.placeholder
}
id={data.id && data.id}
disabled ={data.disabled && data.disabled }
value={
formItemData &&
formItemData[data.id] &&
formItemData[data.id].ID === ''
? values &&
values[data.id] &&
values[data.id].VALUE
: formItemData &&
formItemData[data.id] &&
formItemData[data.id]
.VALUE
}
className={
data.inputItemClassName &&
data.inputItemClassName
}
onChange={e =>
this.handleOnChange(e)
}
/>
</Form.Item>
</div>
);
})}
</div>
{childComponent}
</div>
);
}
}
export default InputComponent;
I want to test addEventListener/RemoveEventListener for an Element.
class Image extends PureComponent {
state = {
isLoaded: false,
};
componentDidMount() {
if (!this.props.src) return;
this.imageToLoad = document.createElement('img');
this.imageToLoad.addEventListener('load', this.loadImage);
this.imageToLoad.src = this.props.src;
}
componentWillUnmount() {
if (!this.imageToLoad) return;
this.imageToLoad.removeEventListener('load', this.loadImage);
}
loadImage = () => {
this.setState({ isLoaded: true }, () => {
this.myimg.src = this.imageToLoad.src;
});
}
render() {
const { className, src, alt } = this.props;
const { isLoaded } = this.state;
if (isLoaded === false || !src) return '';
return (
<img
className={className}
ref={img => (this.myimg = img)}
src={src}
alt={alt}
/>
);
}
}
Test code:-
it('should add event listener on mount', () => {
const elementMock = { addEventListener: jest.fn() };
jest.spyOn(Image.prototype, 'myimg').mockImplementation(() => elementMock);
expect(elementMock.addEventListener).toBeCalledWith('load', expect.any(Function), false);
});
But it is not working as expected.