Want to clear input values of dynamic form in React? The problem is that the inputs are not controlled by state as you have deduced. We should create an updated object for each item from your API, giving it a value prop.
index.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 | import React from "react"; import ReactDOM from "react-dom"; import Cart from "./Cart"; import "./styles.css"; class App extends React.Component { constructor(props) { super(props); this.state = { Items: [], itemvalues: [{}] }; this.onChangeText = this.onChangeText.bind(this); this.getItems = this.getItems.bind(this); this.handleReset = this.handleReset.bind(this); this.handleSubmit = this.handleSubmit.bind(this); this.findFieldIndex = this.findFieldIndex.bind(this); this.trimText = this.trimText.bind(this); } getItems = () => { /*if the data is coming from an API, store it in an array then .map() over it. we can add a value prop to the object like: so you can do something like: const newItems = [...apiData].map((item) => { return { ...item, value: "" } }) this.setState({ Items: newItems }) */ this.setState({ Items: [ { name: "item1", description: "item1", group: "groupA", dtype: "str", value: "" }, { name: "item2", description: "item2", group: "groupA", dtype: "str", value: "" }, { name: "item3", description: "item3", group: "groupB", dtype: "str", value: "" }, { name: "item4", description: "item4", group: "groupB", dtype: "str", value: "" } ] }); }; onChangeText = e => { const updatedItems = [...this.state.Items].map(item => { if (item.name === e.target.name) { return { ...item, value: e.target.value }; } else { return item; } }); const updatedItemValues = [...updatedItems].reduce((obj, curr) => { if (!obj[curr.group]) { obj[curr.group] = []; } obj[curr.group] = [...obj[curr.group], { [curr.name]: curr.value }]; return obj; }, {}); this.setState({ ...this.state, Items: updatedItems, itemvalues: updatedItemValues }); }; findFieldIndex = (array, name) => { return array.findIndex(item => item[name] !== undefined); }; trimText(str) { return str.trim(); } handleReset = () => { const resetedItems = [...this.state.Items].map(item => { return { ...item, value: "" }; }); this.setState( { ...this.state, Items: resetedItems, itemvalues: [] }, () => console.log(this.state) ); }; handleSubmit = () => { console.log(this.state.itemvalues); }; render() { return ( <div> { <Cart Items={this.state.Items} getItems={this.getItems} handleSubmit={this.handleSubmit} handleReset={this.handleReset} onChangeText={this.onChangeText} /> } </div> ); } } |
Cart.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | import React, { useEffect } from "react"; import Form from "./Form"; const Cart = props => { useEffect(() => { props.getItems(props.Items); }, []); return ( <div> <Form Items={props.Items} onChangeText={props.onChangeText} /> <button onClick={props.handleSubmit}>Submit</button> <button onClick={props.handleReset}>Reset</button> </div> ); }; export default Cart; |
The Cart component can remain mostly the same, we do not need to pass in props.items to useEffect()
dependency.
Form.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | import React from "react"; const Form = props => { return ( <div> {props.Items.map(item => { return ( <input name={item.name} placeholder={item.description} data-type={item.dtype} data-group={item.group} onChange={e => props.onChangeText(e)} value={item.value} /> ); })} </div> ); }; export default Form; |
If you like this question & answer and want to contribute, then write your question & answer and email to freewebmentor[@]gmail.com. Your question and answer will appear on FreeWebMentor.com and help other developers.