0
votes

I use useState hook:

const [newGlass, setNewGlass] = useState({});

Then I make "input" as controlled in my component:

<input ref={nameRef} value={newGlass.name} onChange={handleNameChange} type="text" className="form-control" name="name" id="name" />

My "handleNameChange" function:

function handleNameChange(e) {
    newGlass.name = e.target.value;
    setNewGlass(newGlass);
}

My submit function:

function submit() {
    console.log("submited", newGlass, nameRef, whyRef);
    newGlass.id = i++;
    let newState = [Object.assign({}, newGlass), ...glassWords];
    setNewGlass({});
    nameRef.current.value = "";

    setGlassWords(newState);
}

The question is why if I try to make input empty after Submit it don't work?

Only refs helps me. If I try just to set "setNewGlass({});" values in my form inputs stay the same as before Submit.

If I try to "setNewGlass({name: ""});" - then after it I couldn't change input value at all.

What I do wrong? How to make correct controlled input without refs?

May be I should not use object for useState? But in docs I saw that this hook works fine with objects.

P.S. I try to make "handleNameChange" immutable but it has no effect.

UPD. Oh I forgot to tell that if I use separate "const [newGlassName, setNewGlassName] = useState("");" it all works fine and my input become empty after "setNewGlassName("");".

But I have about 13 input fields in my form and I try to understand how to use Object in useState hook.

UPD2. I try to add "console.log(newGlass);" to my component and remove refs. Now when I make Submit my component function starts and "console.log(newGlass);" say "{}". This means that my inputs had to become empty, but they are not!

This leads to thought that React may be compare states by references and do not start re-render of my component? I'm confused...

Can anybody please help me what can I try to do to force React re-render? Or it will be better if I will help React to understand when he need to make re-render? Or it will be better to use class instead of function component?

I guess I need something like "shouldComponentUpdate()" but for functional component, not class you know?

2
function handleNameChange(e) { setNewGlass({name: e.target.value}); } - Noman Gul

2 Answers

0
votes

First of all, you have to change the handleNameChange function. and it could be something like this:

function handleNameChange(e) {
    setNewGlass(e.target.value);
}

then you have to change the onSubmit function.

function submit(e) {
    //dont forget to use e.preventDefault()
    e.preventDefault();
    let currentName = newGlass;
    currentName.id = 2;
    setGlassWord(currentName)
    setNewGlass({})
}

I think it should work, by the way you didn't ask a detailed question and if you want to get better answers you should consider adding more code to your question.

-2
votes

I am not familiar with the useState hook, here is what I would do:

class MyComponent extends React.Component {
  constructor(props) {
    this.state = {name: ""}
    this.handleNameChange = this.handleNameChange.bind(this)
  }

  handleNameChange() {
    // call your setGlassWords if you need
    this.setState({name: e.currentTarget.value})
  } 

  render() {
    return (
      <input value={this.state.name} onChange={handleNameChange} type="text" className="form-control" name="name" id="name" />
    )
  }
}