Home > Enterprise >  React does not change input value
React does not change input value

Time:10-18

I am a React beginner but I did a very basic form component that does not work! It is this. What is the trouble? Maybe the value={prop.value}?

ReactDOM
    .createRoot(document.getElementById('root'))
    .render(<App />);

function App() {
    const data = [
        {
            type: 'text',
            name: 'name',
            label: 'Name',
            value: 'Alfred'
        },
        {
            type: 'number',
            name: 'amount',
            label: 'Amount',
            value: 23
        },
        {
            type: 'date',
            name: 'birthday',
            label: 'Date',
            value: '1987-02-01'
        }
    ];

    return <Form data={data} />;
}

function Form(props) {
    let [data, setData] = React.useState(props.data);
    const handleChange = (e) => {
        let elem = e.target;
        setData((data) => {
            const prop = data[elem.dataset.index];
            console.log('Input \''   prop.name   '\' becomes from \''   prop.value   '\' to \''   elem.value   '\'');
            data[elem.dataset.index].value = elem.value;
            return data;
        });
    };

    return (
        <form>
            {data.map((prop, i) => {
                const id = "input-"   prop.name;
                return (
                    <div key={prop.name}>
                        <label htmlFor={id}>{prop.label}</label>
                        <span>: </span>
                        <input
                            type={prop.type}
                            id={id}
                            value={prop.value}
                            onChange={handleChange}
                            data-index={i}
                        />
                    </div>
                );
            })}
        </form>
    );
}
<script crossorigin src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>
<div id="root"></div>

CodePudding user response:

React's state is immutable, so you cannot modify the array data directly.

You have to change return data to return [...data] which is to clone your array to a new value in setData of handleChange

ReactDOM
    .createRoot(document.getElementById('root'))
    .render(<App />);

function App() {
    const data = [
        {
            type: 'text',
            name: 'name',
            label: 'Name',
            value: 'Alfred'
        },
        {
            type: 'number',
            name: 'amount',
            label: 'Amount',
            value: 23
        },
        {
            type: 'date',
            name: 'birthday',
            label: 'Date',
            value: '1987-02-01'
        }
    ];

    return <Form data={data} />;
}

function Form(props) {
    let [data, setData] = React.useState(props.data);
    const handleChange = (e) => {
        let elem = e.target;
        setData((data) => {
            const prop = data[elem.dataset.index];
            console.log('Input \''   prop.name   '\' becomes from \''   prop.value   '\' to \''   elem.value   '\'');
            data[elem.dataset.index].value = elem.value;
            return [...data]; //the change is here
        });
    };

    return (
        <form>
            {data.map((prop, i) => {
                const id = "input-"   prop.name;
                return (
                    <div key={prop.name}>
                        <label htmlFor={id}>{prop.label}</label>
                        <span>: </span>
                        <input
                            type={prop.type}
                            id={id}
                            value={prop.value}
                            onChange={handleChange}
                            data-index={i}
                        />
                    </div>
                );
            })}
        </form>
    );
}
<script crossorigin src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>
<div id="root"></div>

  • Related