i created an input, when you right something and click on the button, value adds to our state, now im trying to update select option from state like this:
const NewGroup = () => {
const [group, setGroup] = useState([]);
const addToGroup = (e) => {
const newGroup = group;
newGroup.push(e.target.previousElementSibling.value);
setGroup(newGroup);
};
return (
<div>
<input type="text" name="" id="" />
<button onClick={addToGroup}>submit</button>
<div>
<select name="" id="">
{group.map((category) => {
return <option value=''>{category}</option>;
})}
</select>
</div>
</div>
);
};
export default NewGroup;
but nothing did happened.
CodePudding user response:
You can introduce another useState()
for writing into <input>
element. And when the Submit button is pressed, you only push the someText
to the group
array.
const NewGroup = () => {
const [group, setGroup] = useState([]);
const [someText, setSomeText] = useState("");
const addToGroup = (e) => {
// Takes up all the present elements(of array group) and adds new element (search)
let temp = [...group, someText];
setGroup(temp);
};
return (
<div>
<input type="text" name="" id="" value={someText} onChange={(e) => { setSomeText(e.target.value); }} />
<button onClick={addToGroup}>submit</button>
<div>
<select name="" id="">
{group.map((category, index) => {
return (
<option key={index} value="">
{category}
</option>
);
})}
</select>
</div>
</div>
);
}
export default NewGroup;
Here's the link to the working app https://codesandbox.io/s/boring-ptolemy-0cwzmi?file=/src/App.js
CodePudding user response:
First, you should not be getting the value of your input by using the DOM directly, instead you should be using a Ref.
Secondly, the issue is that you're mutating the group value directly instead of copying it. When you call setGroup, React doesn't realize there was any change (because the previous value equals the current value). Instead you want to copy the array and add your new element:
// Previously: const newGroup = group;
const newGroup = [...group];
That should be all you have to do to get your code to work. However, I simplified and cleaned it up a little more with inline comments below.
const NewGroup = () => {
// Here's where our input will be stored so we can use it later (instead of querying the dom directly)
const inputRef = React.useRef();
const [group, setGroup] = React.useState([]);
// Use React.useCallback so the function doesn't change on every render
const addToGroup = React.useCallback((e) => {
// We call setGroup with a function that returns the new group value. The first argument is the current group value. We return a new array by spreading the existing value and adding our new value
setGroup((v) => [...v, inputRef.current.value]);
}, []);
return (
<div>
<input type="text" ref={inputRef} name="" id="" />
<button onClick={addToGroup}>submit</button>
<div>
<select name="" id="">
{group.map((category) => {
return (
<option value="" key={category}>
{category}
</option>
);
})}
</select>
</div>
</div>
);
};