Carlos Escobar
Carlos Escobar

Reputation: 434

onchange input not working useState in react

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

Answers (1)

ABDELJALIL AIT ETALEB
ABDELJALIL AIT ETALEB

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

Related Questions