Jacki
Jacki

Reputation: 672

React useState, value of input doesnt update

I wish to generate inputs based on json, so first I set it to initial state, then in child componenet I want to modify it's field, thing is that component doesnt update... It renders once and have no idea how to make it be updated each time when input onChange change it's value. Any idea how to make value of input be updated each time when I type something?

PARENT

 function App() {
      const [inputValue, setInputValue] = useState(chunkingRow);


  const handleChunkingChange = (e, index) => {
    let inputContent = inputValue;
    const reg = new RegExp(/^[0-9]+$/);

    if (e.target.value.match(reg)) {
      inputContent[index] = {
        ...inputContent[index],
        content: e.target.value,
      };

      setInputValue(inputContent);
      console.log(inputValue);
    } else console.log('not a number')
  };

  return (
    <div>
      <Wrapper>
        {Chunk(inputValue, handleChunkingChange)}
      </Wrapper>
    </div>
  );
}

CHILD

const Chunk = (inputValue, handleChunkingChange) => {

return(
  <div>
    {inputValue.map((el, index) => (
      <div key={index}>
        <p>{el.title}</p>
        {console.log(el.content)}
        <input
          type="text"
          onChange={(e, i) => handleChunkingChange(e, index)}
          value={el.content}
        />
      </div>
    ))}
  </div>
);
}

link to demo https://codesandbox.io/s/stoic-mirzakhani-46exz?file=/src/App.js

Upvotes: 1

Views: 1651

Answers (3)

curious.netter
curious.netter

Reputation: 814

You are mutating the state object.

let inputContent = inputValue;

That's why the state is not re-rendered. Change it to

 let inputContent = [...inputValue];

An example of mutating objects. React compares previous state and current state and renders only if they are different.

const source = { a: 1, b: 2 };
const target = source;
console.log(target);
console.log(target === source); =  true
target.b = 99;
console.log({target});
console.log({source}); //source == target due to mutation
console.log(source === target); = true

Remember, never mutate.

Upvotes: 1

radovix
radovix

Reputation: 3207

Not completely sure why this happens, but probably because of the way you handle the input change. It seems to me that component doesn't recognize that array changed. How I managed to fix your code is replacing line 9 in App component with following code:

let inputContent = [...inputValue];

By doing that, array's reference is changed and components are updated.

Upvotes: 3

MohammadAmin Mohammadi
MohammadAmin Mohammadi

Reputation: 1211

Just update your code as follow:

let inputContent = [ ...inputValue ];

Upvotes: 1

Related Questions