Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

react functional component: After first value not able to continue type the value in input element

I’m trying to update value in react functional compoenent through input element but after the first value I’m unable to type

My Code:

import React from "react";
import "./App.css";

const { useState } = React;
function App() {
    const [items, setItems] = useState([
        { value: "" },
        { value: "" },
        { value: "" },
    ]);
    const [count, setCount] = useState(0);
    const Item = React.memo(({ id, value, onChange }) => {
        return (
            <div className="item">Item
                <input
                    onChange={(e) => onChange(id, e.target.value)}
                    value={value}
                />
            </div>
        );
    });
    return (
        <div className="app">
            <h1>Parent</h1>
            <p style={{marginTop: '20px'}}>Holds state: {count}, Does't passes to it items</p>
            <p style={{marginTop: '20px'}}>{JSON.stringify(items)}</p>
            <button onClick={() => setCount((prev) => prev + 1)} style={{marginTop: '20px'}}>
                Update Parent
            </button>
            <ul className="items" style={{marginTop: '20px'}}>
                {items.map((item, index) => {
                    return (
                        <Item
                            key={index}
                            id={index}
                            value={item.value}
                            onChange={(id, value) =>
                                setItems(
                                    items.map((item, index) => {
                                        return index !== id
                                            ? item
                                            : { value: value };
                                    })
                                )
                            }
                        />
                    );
                })}
            </ul>
        </div>
    );
}

export default App;

enter image description here

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

You should move the Item declaration outside the App component. Having a component declaration inside another one is almost always a bad idea. Explanation below.

import React, { useState } from "react";

const Item = React.memo(({ id, value, onChange }) => {
  return (
    <div className="item">
      Item
      <input onChange={(e) => onChange(id, e.target.value)} value={value} />
    </div>
  );
});

function App() {
  const [items, setItems] = useState([
    { value: "" },
    { value: "" },
    { value: "" }
  ]);
  const [count, setCount] = useState(0);

  return (
    <div className="app">
      <h1>Parent</h1>
      <p style={{ marginTop: "20px" }}>
        Holds state: {count}, Does't passes to it items
      </p>
      <p style={{ marginTop: "20px" }}>{JSON.stringify(items)}</p>
      <button
        onClick={() => setCount((prev) => prev + 1)}
        style={{ marginTop: "20px" }}
      >
        Update Parent
      </button>
      <ul className="items" style={{ marginTop: "20px" }}>
        {items.map((item, index) => {
          return (
            <Item
              key={index}
              id={index}
              value={item.value}
              onChange={(id, value) =>
                setItems(
                  items.map((item, index) => {
                    return index !== id ? item : { value: value };
                  })
                )
              }
            />
          );
        })}
      </ul>
    </div>
  );
}

export default App;

When a component definition is inside another component, React will re-declare the inner component every time the parent re-renders. This means, that any state held by the inner component will be lost.
In your case, since every time there is an entirely new component, the input was not the same input as in the previous render. This means that the input that was in focus in the previous render is not present anymore, and the new input is not focused anymore.

You should also probably change

setItems(
    items.map((item, index) => {
        return index !== id ? item : { value: value };
    })
)

to

    prev.map((item, index) => {
        return index !== id ? item : { value: value };
    })
)

It’s a good idea to use the function notation for set state when the new state depends on the old state value.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading