1

How to clear the value inside the input in function Admin after I click the "Add" button? Should i use another class based component instead of a functional component?

I have set the value of one of the input box as : value={props.item} and in the this.setState I update the value of item as item:"".

  AddInfo(info){
    let s = this.state.products;
    let obj ={name:""};
    obj.name=info.productName;

    s.push(obj);

    this.setState({
      products:s,
      item:"" //Here i set the value of item equal to an empty string.
    })
    console.log(this.state.products);
  }



function Admin(props){

    let productName="";

    return (
        <div>            
            <input type="text" required placeholder="Product Name" onChange={(e)=>{productName=e.target.value}} value={props.item}></input><br/>

   <button type="Submit" onClick{(e)=>props.AddInfo({productName})}>Add</button>
     </div>
    )
}
isherwood
  • 58,414
  • 16
  • 114
  • 157
Hardik Aswal
  • 227
  • 3
  • 15
  • Hi Hardik, I'd like to answer your question, but please minimize your code snippet. It seems you just copied code to the snippet. Pleas leave only what's relevant to your question, so it is easier to answer. The various routes are irrelevant. AddInfo also seems irrelvant. – Ben Carp Aug 09 '19 at 12:28
  • Done. AddInfo isn't irrelevant since I have used this.setState in AddInfo to set this.state.products equal to s and also updated the value of item:"" which i think is something wrong since the value of item never changed in the first place :( – Hardik Aswal Aug 09 '19 at 12:48

2 Answers2

0

You have to save your input within a local state of the input function:

 AddInfo(info){
    let s = this.state.products;
    let obj ={name:""};
    obj.name=info.productName;

    s.push(obj);

    this.setState({
      products:s,
    })
    console.log(this.state.products);
    }



function Admin(props){

    const [productName, setProductName] = useState('');

    return (
        <div>            
            <input type="text" required placeholder="Product Name" onChange={(e)=> setProductName(e.target.value) value={productName}></input><br/>
   <button type="Submit" onClick{(e)=> {props.AddInfo({productName}); setProductName('')}}>Add</button>
 </div>
)
}

This will work for you, since you are not mutating the productName variable anymore but now you are saving it in a local state of that input function.

Hope this helps!

Domino987
  • 8,475
  • 2
  • 15
  • 38
  • It says 'useState','setproductName' is not defined. – Hardik Aswal Aug 09 '19 at 17:31
  • Did you import useState, and in which lines does it give the error? – Domino987 Aug 09 '19 at 17:37
  • I created a codepen for you: https://codepen.io/Domino987/pen/WVgBOr?editors=1011 – Domino987 Aug 09 '19 at 17:54
  • https://codepen.io/hardik150/pen/PMdrKW Used it. Doesn't work for some reason (Sorry I am new to this) – Hardik Aswal Aug 09 '19 at 18:09
  • Sorry I didn't add value={productName}. It worked now.Thank a lot I literally spent the whole day getting this done. – Hardik Aswal Aug 09 '19 at 18:16
  • I used your solution in my code and it works flawlessly, but the same isn't the case with a file input that I have added in my code. Can you please help me out? https://codepen.io/hardik150/pen/zgmGqz – Hardik Aswal Aug 10 '19 at 06:38
  • You are making the same error again, you have to read some docs to understand what is happening. You cannot create variables in a functional component just like this and expect it to persist (it gets overwritten on every render), you have to use useState for each variable you track: https://codepen.io/Domino987/pen/MNPeRZ?editors=0011 – Domino987 Aug 10 '19 at 06:53
  • In this codepen you created, I'll have to give my input some value and in the button write setProductPicture(" ") , right? When I give {productPicture} as a value it shows "This input element accepts a filename, which may only be programmatically set to the empty string." – Hardik Aswal Aug 10 '19 at 07:12
  • The input is a little bit more tricky, the value reset does not work for the file type. Here is another SO answer, which covers it:https://stackoverflow.com/questions/42192346/how-to-reset-reactjs-file-input – Domino987 Aug 10 '19 at 07:21
  • I'll try to figure it out :) Would it make more sense to just start from scratch with a class based component instead of a functional component since I want to add features like remove,update etc? – Hardik Aswal Aug 10 '19 at 08:07
  • It depends on the complexity. If you have more than few functions and states, it would be better, since it improves readability and makes it easier to maintain. – Domino987 Aug 10 '19 at 08:21
0
  • Admin is like a form, and the main decision you have to make is rather you want it to be controlled (info is stored in stated, and state is reflected in the ui), or uncontrolled (info is taken from the dom once 'Add' is clicked.
  • Since you want to empty the input once 'Add' is clicked it makes sense to make this component controlled.
  • The next decision is rather you want it to be a functional component, or a class component. In nowadays it doesn't really matter (functional components can now use state with the state hook).
  • To store state in you functional component use React's useState hook.
function Admin({addInfo}){
    const [productName, setProductName] = useState(")

    return (
        <div>            
            <input 
                 type="text" 
                 placeholder="Product Name" 
                 onChange={(e)=>{
                     setProductName(e.target.value)
                 } 
                 value={prodcutName}>
             </input>
             <button 
                 onClick{(e)=>{
                     props.addInfo({productName})
                     setProductName("")  // Will set the input to an empty string
                 }
             >
                  Add
             </button>
     </div>
    )
}
Ben Carp
  • 24,214
  • 9
  • 60
  • 72
  • I hope my answer helps. A few comments on smaller issues: - required won't have any effect (it is used in forms when jquery is involved, and it hints to a validator that it is required. This is not the case. If you want it to be required implement it on the buttons click handler. 2. If you start AddInfo with a capital it looks like a component. If it's a function (or a method) it will be more clear if it starts with a small letter. – Ben Carp Aug 09 '19 at 13:16
  • Thanks for the response. It says 'useState','setproductName' is not defined. Sorry I am new to this and haven't quite picked up a lot yet. And yes, I removed the 'required' since it doesn't do anything – Hardik Aswal Aug 09 '19 at 17:31
  • Done.Thanks a lot – Hardik Aswal Aug 09 '19 at 18:19
  • My pleasure. If you found it helpful you can upvote, or even mark the answer as accepted :-) – Ben Carp Aug 09 '19 at 19:30
  • Upvoted :) Can you also help me out with the same thing but with a file input this time? Here's what I am doing https://codepen.io/hardik150/pen/zgmGqz – Hardik Aswal Aug 09 '19 at 19:40
  • Unfortunatly I don't have much experience with uploading files this way. When you find an answer useful you can upvote it using the upward triangle. – Ben Carp Aug 09 '19 at 19:47
  • 1
    Oh okay thanks again. And yeah I upvoted it but it won't show because of low reputation :P – Hardik Aswal Aug 09 '19 at 19:52
  • If you use an "npm environment" you can use a dependency to upload files. Check out codeSandBox or StackBlitz and npm. – Ben Carp Aug 09 '19 at 19:55