Reputation: 434
I'm trying to set up an onChange
for a text box input but I can't work out why it isn't working... I've logged the output inside the handler function and the value seems to update. The problem is that when I'm passing this to the input component it shows an empty string still. Not sure why?
A second question I have is that I tried destructuring the input config initial value and the console yields an error saying the value is read-only. Could anyone explain why? This option is currently commented out.
See the component logic below:
import React, { useState } from 'react';
import classes from './BioSection.css';
import Input from '../../UI/Input/Input';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faCameraRetro, faUser } from '@fortawesome/free-solid-svg-icons';
const BioSection = () => {
const [addingBio, setAddingBio] = useState(false);
const [inputConfig, setInputConfig] = useState({
elementType: 'textarea',
elementConfig: {
placeholder: 'Bio',
},
value: '',
length: 0,
validation: {
required: true,
minLength: 10,
maxLength: 100,
},
valid: false,
});
const checkValidity = (value, rules) => {
let isValid = true;
if (rules.minLength) {
isValid = value.length >= rules.minLength && isValid;
}
if (rules.maxLength) {
isValid = value.length <= rules.maxLength && isValid;
}
return isValid;
};
const addBio = () => {
setAddingBio(true);
};
const saveBio = () => {
setAddingBio(!addingBio);
//request POST http
};
const cancelBioUpdate = () => {
setAddingBio(!addingBio);
};
const textAreaChangedHandler = (e) => {
console.log(e.target.value);
const copyOfInputConfig = inputConfig;
copyOfInputConfig.value = e.target.value;
copyOfInputConfig.length = e.target.value.length;
copyOfInputConfig.valid = checkValidity(
copyOfInputConfig.value.trim(),
copyOfInputConfig.validation
);
console.log(copyOfInputConfig);
// const { value, length, valid, validation } = copyOfInputConfig;
// value = e.target.value;
// value = e.target.value;
// length = e.targer.value.length;
// valid = checkValidity(copyOfInputConfig.value.trim(), validation);
let formIsValid = true;
for (let inputIdentifier in copyOfInputConfig) {
formIsValid = copyOfInputConfig.valid && formIsValid;
}
setInputConfig(copyOfInputConfig);
};
return (
<div className={classes.BioSection}>
{addingBio ? (
<div className={classes.UserBio}>
<Input
bioSection
key={inputConfig.elementType}
elementType={inputConfig.elementType}
elementConfig={inputConfig.elementConfig}
value={inputConfig.value}
valueLength={inputConfig.value.length}
invalid={!inputConfig.valid}
shouldValidate={inputConfig.validation}
maxCharacters={inputConfig.validation.maxLength}
changed={(e) => {
textAreaChangedHandler(e);
}}
/>
<div className={classes.BioButtonHolder}>
<button onClick={cancelBioUpdate}>cancel</button>
<button onClick={saveBio}>save</button>
</div>
</div>
) : (
<div>
<span>add travel bio</span>
<button onClick={addBio}>add bio</button>
</div>
)}
</div>
);
};
export default BioSection;
Upvotes: 0
Views: 609
Reputation: 146
why don't you setState directly like this??
setInputConfig({
...inputConfig,
value: e.target.value,
length: e.target.value.length,
valid: checkValidity(
e.target.value.trim(),
inputConfig.validation
),
});
as for the second question you are trying to assign new value to a constant.
Upvotes: 1