React, states don't match - javascript

I'm trying to check if two password fields match and then update a state to true or false based on this. I am using Refs for the input fields and running matchPw on input change.
However the state does not update first time and go out of sync. This is what I have tried:
const matchPw = () => {
let enteredValue = pwOne.current.value;
let enteredRepeatedValue = pwTwo.current.value;
if (enteredValue === enteredRepeatedValue) {
setError((prevState) => ({
...prevState,
pwMatch: true,
}));
console.log("match: " + pwError.pwResetMatchWarning);
} else {
setError((prevState) => ({
...prevState,
pwMatchW: false,
}));
console.log("do not match: " + pwError.pwResetMatchWarning);
}
}

Related

when expire date entered, automatic slash

There is a credit card component. It asks the user to enter credit card information. However, I want to automatically put a slash between the day and month when the user enters the credit card expiration date. I searched the expiration date entry as "auto slash when 2 digits are entered" but I haven't been successful yet.
i can write; 0614
The format i want; 06/14
How can I solve it?
js
const [expDateValidationState, setExpDateValidationState] = useState({
error: false,
helperText: '',
});
const expDateOnChange = (event) => {
if (expDateValidator(event.target.value)) {
setExpDateValidationState({ error: false, helperText: '' });
setPaymentInfo({
...paymentInfo,
expDate: event.target.value === '' ? null : event.target.value,
});
} else {
setExpDateValidationState({
error: true,
helperText: 'Please enter your expire date.',
});
setPaymentInfo({
...paymentInfo,
expDate: null,
});
}
const handleExpDateChange = (event) => {
expDateOnChange(event);
handleInputChange(event);
};
validator
export const expDateValidator = (expDate) => {
const expDateRegex = /^(0[1-9]|1[0-2])\/?([0-9]{4}|[0-9]{2})$/;
return expDateRegex.test(expDate);
};
html
<AS.TextField
placeholder="aa/YY"
inputProps={{ maxLength: 5 }}
onChange={handleExpDateChange}
error={expDateValidationState.error}
helperText={expDateValidationState.helperText}
name="expDate"
value={paymentInfo.expDate}
/>
Try this one
const expDateOnChange = (event) => {
if (expDateValidator(event.target.value)) {
setExpDateValidationState({ error: false, helperText: '' });
let value = event.target.value;
if (value.length===2) value += "/"
setPaymentInfo({
...paymentInfo,
expDate: event.target.value === '' ? null : value,
});
} else {
setExpDateValidationState({
error: true,
helperText: 'Please enter your expire date.',
});
setPaymentInfo({
...paymentInfo,
expDate: null,
});
}
When I change some data I usually put it in the state. If you also keep your data in the state, you can modify your handleExpDateChange to something like this:
const [expirationDate, setExpirationDate] = useState();
const handleExpDateChange = (event) => {
if (event.target?.value?.length === 2 && expirationDate.length < 3) {
setExpirationDate(event.target.value + '/')
} else {
setExpirationDate(event.target.value)
}
}
This can be simplified if you use ternary expression or in any other way but this is just very simple and the first thing that came to my mind.
Hope this will be helpful.

How to update state for function that relies on if statement from state?

I have an array called values:
values = RAW_VALUES.map((data) => {
return {
id: data.id,
name: data.name,
value: financials[data.id],
add: false,
subtract: false,
change: "",
newValue: "",
};
});
and a function:
updateValues(val, index) {
let { values } = this.state;
if (!isNaN(val)) {
values[index].change = parseFloat(val);
if(values[index].add){ //this checks if add property is true
values[index].newValue = values[index].value + values[index].change
}
this.setState({
values,
});
}
}
I have a button called 'Add' which toggles the add field of each index in values.
To update values[index].newValue, the user currently needs to set add to true first and then type in the updated value.
How can I ensure that the value is also updated if the user first types in the value, and then sets add to true ?
This is how updateValues is called in render:
<MetricInput
value={values[index]?.change}
onChange={(e) =>
this.updateValues(e.target.value, index) //function
}
/>
Edit: There are two buttons, add and subtract. if add is set to true then I'd want to do values[index].newValue = values[index].value + values[index].change
Else, if subtract is set to true, I'd do values[index].newValue = values[index].value - values[index].change
Not withstanding there are better ways to update an array of objects, can you not consider ignoring the if(values[index].add) condition and just set values[index].add = true ?
updateValues(val, index) {
let { values } = this.state;
if (!isNaN(val)) {
values[index].change = parseFloat(val);
values[index].newValue = values[index].value + values[index].change
values[index].add = true
this.setState({
values,
});
}
}
Update - Keep the above, and consider making numbers Positive or Negative depending on Add/Subtract
const onAdd = (index) => {
let values = this.state.values;
values[index].newValue = Math.abs(values[index].newValue)
this.setState({ values })
}
const onSubtract = (index) => {
let values = this.state.values;
values[index].newValue = -Math.abs(values[index].newValue)
this.setState({ values })
}

react-native-calendar : selected ON/OFF when date is selected

I am using react-native-calendar for my project. I can mark on the calendar when I press on a date. But I want to mark off when marked date is pressed again.
This is my function code:
onDayPress = (day) => {
const _selectedDay = Moment(day.dateString).format(_format);
this.setState(({pressedDate}) => ({
pressedDate: {
...pressedDate,
[_selectedDay] : {
selected: true
}
},
selectedDay:_selectedDay
}))
console.log(this.state.pressedDate, 'this.state.pressedDate')
}
In my calendar
<Calendar
style={styles.calendarBox}
markedDates={this.state.pressedDate}
onDayPress={this.onDayPress}
markingType={'multi-dot'}
monthFormat={'yyyy MMMM'}/>
Is there a way I can mark on and off dates? Also, I want only to mark up to three dates. Is this possible?
Also, when I console.log('this.state.pressedDate') I get undefined at first. When I click on it again then I get the value any idea why this is happening?.
Is there a way I can mark on and off dates?
As you can see in Calendar implementation, it only updates when you pass difference current to this component. You can do this trick:
_onDayPress = day => {
const { dateString } = day;
const { markedDates } = this.state;
const isMarkedBefore = !!(
markedDates[`${dateString}`] &&
markedDates[`${dateString}`].selected
);
markedDates[`${dateString}`] = { selected: !isMarkedBefore };
this.setState(
{ ...this.state, markedDates, current: null },
() => {
this.setState({
...this.state,
current: dateString
});
});
};
...
<Calendar
style={styles.calendarBox}
current={this.state.current}
markedDates={this.state.markedDates}
onDayPress={this._onDayPress}
markingType={'multi-dot'}
monthFormat={'yyyy MMMM'}/>
when I console.log('this.state.pressedDate') I get undefined at first. When I click on it again then I get the value any idea why this is happening?.
setState is asynchronous function so if you want to see what your state change after that you should log in second callback parameter like
this.setState({...someState}, () => {
console.log(this.state);
})

How do I update an array of objects in component state?

I am trying to update the property of an object which is stored in an array.
my state looks something like this:
state = {
todos: [
{
id: '1',
title: 'first item,
completed: false
},
{
id: '2',
title: 'second item,
completed: false
}
],
}
What I am trying to do is access the second element in the 'todos' array and update the completed property to either false -> true or true -> false.
I have a button with the handler for update, and my class method for the update looks like this:
onUpdate = (id) => {
const { todos } = this.state;
let i = todos.findIndex(todo => todo.id === id);
let status = todos[i].completed
let updatedTodo = {
...todos[i],
completed: !status
}
this.setState({
todos: [
...todos.slice(0, i),
updatedTodo,
...todos.slice(i + 1)
]
});
}
While this does work, I want to find out if there is a more concise way of achieving the same result; I tried to use Object.assign(), but that didn't work out because my 'todos' is an array, not an object. Please enlighten me with better code!
It would be best to use update function to make sure you don't work on outdated data:
onUpdate = (id) => {
this.setState(prevState => {
const copy = [...prevState.todos];
const index = copy.findIndex(t => t.id === id);
copy[index].completed = !copy[index].completed;
return { todos: copy }
})
}
You can simply copy your todos from state, then make edits, and after that put it back to the state
onUpdate = (id) => {
var todos = [...this.state.todos]
var target = todos.find(todo => todo.id == id)
if (target) {
target.completed = !target.completed
this.setState({ todos })
}
}

How can I disable checkboxes and radio buttons from separate components?

Running into this ReactJS (with Redux) issue:
If premium white isn’t selected, gloss finish should be disabled. The radio button (premium) and checkbox (gloss) have separate methods in separate components – looks like they are both using state to send data.
Here’s the checkbox
buildCheckbox(item) {
return (
<Checkbox
key={item.key}
label={item.display}
name={item.key}
checked={this.props.order[item.key] || false}
onChange={checked => this.handleCheck(checked, item.key)}
disabled={item.disabled(this.props.order)}
/>
);
}
And the handleclick method used
handleCheck(checked, key) {
const { params, updateOrder } = this.props;
const { sessionId } = params;
// if doulbeSided option is removed, then clear the inside file.
if (key === 'doubleSided' && !checked) {
updateOrder(sessionId, { inside: null });
}
// set ink coverage based on printed flag
if (key === 'printed') {
const inkCoverage = checked ? 100 : 0;
updateOrder(sessionId, { inkCoverage });
}
// if unprinted, remove doublesided and gloss options
if (key === 'printed' && !checked) {
updateOrder(sessionId, { doubleSided: false });
updateOrder(sessionId, { gloss: false });
}
updateOrder(sessionId, { [key]: checked });
}
And the radio button’s method
onClick(id, ordAttribute) {
const { updateOrder, sessionId, validator } = this.props;
updateOrder(sessionId, { [ordAttribute]: id });
if (validator) validator(ordAttribute);
}
I saw that gloss has a service which is toggling disabled or not via the printed key on state here
gloss: {
display: 'Gloss Finish',
key: 'gloss',
component: 'checkbox',
disabled: state => !state.printed,
},
I’ve thought about creating a fourth radio button and just deleting the gloss option but I’m not sure where it’s being populated from – also thought about using a display none on the styles of the gloss that is activated via the radio button – but am not sure where to start.
just stated a new job and this is the previous employee's code - trying to figure it out. looks like the state is activated via this Action method:
export const updateOrder = (sessionId, payload) => (dispatch, getState) => {
dispatch(updateAction({ ...payload }));
const state = getState();
const ord = getNewOrderForm(state);
const minOrdValue = getMinOrdValue(state);
const { length, width, height, style, blankLength, blankWidth, qty, leadTime, sqFeet } = ord;
const priceMatrix = style ? getPriceMatrix(state)[style.priceMatrix] : null;
if (priceMatrix && style && style.calcPrice) {
dispatch(dispatchNewPrice(ord, style, priceMatrix, minOrdValue));
}
if (shouldCalcBlank({width, length, height}, style)) {
calcBlanks(style, {width, length, height})
.then(blanks => dispatch(updateAction(blanks)))
.catch(err => console.log('error', err))
}
if (blankLength && blankWidth && qty) {
calcSquareFeet({ blankLength, blankWidth, qty })
.then(sqFeet => {
dispatch(updateAction({ sqFeet }));
return sqFeet;
})
.then(sqFeet => sqFeet > 1000)
.then(lrgSqFeet => {
dispatch(updateAction({ lrgSqFeet }));
return lrgSqFeet;
})
.then(lrgSqFeet => {
if (lrgSqFeet && leadTime === 'rush') {
dispatch(updateAction({ leadTime: 'standard' }));
}
});
}
if (sqFeet && (!blankLength || !blankWidth || !qty)) {
dispatch(updateAction({ sqFeet: 0 }));
}
localStorage.setItem(sessionId, JSON.stringify(getNewOrderForm(getState())));
};
i thought about adding a the radio button has an id of 'clearwater' so i thought about adding a bool to this method that could then be accessed as clearwater: false (and when onClick is activated, updateOrder then changes it to clearwater: true, and then the gloss object in the service would then check disabled: state => !state.printed && !state.clearwater (this didn't work):
export const generateNewOrder = (userid, style, sessionId = uuid()) => dispatch => {
localStorage.setItem(
sessionId,
JSON.stringify({
userid,
style,
sessionId,
blindShip: true,
inkCoverage: '100',
printed: true,
})
);
history.push(`/order/new/${style.styleCode}/${sessionId}`);
dispatch(
newOrder({
userid,
style,
sessionId,
blindShip: true,
inkCoverage: '100',
printed: true,
})
);
if (style.type === 'static') {
const { dims, blankLength, blankWidth } = style;
const payload = {
...dims,
blankLength,
blankWidth,
};
dispatch(updateOrder(sessionId, payload));
}
};
I was hoping by changing the Service attached to the checkbox, I could add an additional condition that would cause the disabled functionality to be dependent on the state.boardStyle, but this doesn't seem to work (picture below isn't accurate, i changed it to boardStyle):
http://oi65.tinypic.com/wknzls.jpg
This is using redux -- kind of new to redux -- let me know if I'm missing any info -- I will post anything to get this solved.
Any help would be huge – thanks so much!
i think i figured it out . . .
there's probably a drier way to do this, but here goes:
first i created a new key [bool] (clearwater, set to false) on generateNewOrder method in Actions:
export const generateNewOrder = (userid, style, sessionId = uuid()) => dispatch => {
localStorage.setItem(
sessionId,
JSON.stringify({
userid,
style,
sessionId,
blindShip: true,
inkCoverage: '100',
printed: true,
clearwater: false,
})
);
history.push(`/order/new/${style.styleCode}/${sessionId}`);
dispatch(
newOrder({
userid,
style,
sessionId,
blindShip: true,
inkCoverage: '100',
printed: true,
clearwater: false
})
);
if (style.type === 'static') {
const { dims, blankLength, blankWidth } = style;
const payload = {
...dims,
blankLength,
blankWidth,
};
dispatch(updateOrder(sessionId, payload));
}
};
that gave me access to this state value, which i could then use in the onclick when the radio button was pressed. if the id was clearwater, the bool would be set to true, else it was set to false (only for the other two options because this code is used for other IDs)
onClick(id, ordAttribute) {
const { updateOrder, sessionId, validator } = this.props;
updateOrder(sessionId, { [ordAttribute]: id });
if (validator) validator(ordAttribute);
if (id === 'clearwater') {
updateOrder(sessionId, { clearwater: true });
} else if (id === 'kraft' || id === 'std_white_two_side'){
updateOrder(sessionId, { clearwater: false });
}
}
then all i needed to do was add this to the Service. if it was not printed !printed or not clearwater !clearwater, the checkbox would be disabled
const printing = {
doubleSided: {
display: 'Two Sided Print',
key: 'doubleSided',
component: 'checkbox',
disabled: state => !state.printed,
},
printed: {
display: 'Printed?',
key: 'printed',
component: 'checkbox',
disabled: () => false,
},
gloss: {
display: 'Gloss Finish',
key: 'gloss',
component: 'checkbox',
disabled: state => !state.printed || !state.clearwater,
},
};
I have a working example answering a similar problem, please, have a look. The whole logic is done in redux:
Want to uncheck the node of the tree structure in React JS

Categories

Resources