This is my object:
const [opportunity, setOpportunity] = useState({
name: '',
description: '',
experience: '',
});
I want to store it in the opportunity experience property like a string separated by commas. Like this for example: 'experience_1,experience_2,experience_3'.
But when i type in the input field i want to be able to have space between the words. Like this for example: experience_1 experience_2 experience_3
this is my code for the input field:
<InputField
type='text'
value={opportunity.experience.split(',').join(' ')} // i think i need changes here
onChange={(e) => setOpportunity({ ...opportunity, experience: e.currentTarget.value.split(" ").filter(x => x !== '').toString() })} // i think this works
label={"Experiences"}
/>
Any Help Guys?
CodePudding user response:
Replace .filter(x => x !== '')
with .replace(/\s /g, " ")
and place it before you call the .split()
method. This will replace multiple spaces with a single space, and prevent the user from entering in more than one space at a time, while letting them change the contents of your InputField
component. Remember, .filter() works on a cloned copy of the string while .replace() works on the string itself, which in this case is the event current target value.
Now it should work as intended.
Like so:
<InputField
type="text"
value={opportunity.experience
.split(",")
.map((x) => x.trim()) // Added .trim() to keep consistent spacing...
.join(" ")} // ...before joining
onChange={(e) => {
setOpportunity({
...opportunity,
experience: e.currentTarget.value
.replace(/\s /g, " ") // If you try to use .filter() here, it won't work
.split(" ")
.toString(),
});
}}
label={"Experiences"}
/>
I've also chained a trim operation on each value from the state property with .map()
to keep the spacing consistent during presentation, in the event that the state property was initialized with lots of spaces in between each experience value.
CodePudding user response:
I think this is what I'd do.
First, experience
in your state should be an array because it's easier to deal with. You only need to convert it when you pass it as a prop.
const [opportunity, setOpportunity] = useState({
name: '',
description: '',
experience: [],
});
next, I'd move my handler out to it's own function and give it a name because it's doing enough to get confusing.
This function doesn't need to do anything with the array now since the value in state
is an array.
const handleInput = e => {
const experience = e.currentTarget.value.split(" ").filter(x => x !== '')
setOpportunity({ ...opportunity, experience })
}
Finally, we pass the handleInput
function to the onChange
prop and just pass opportunity.experience.join(' ')
to the value
prop.
<InputField
type='text'
value={opportunity.experience.join(' ')}
onChange={handleInput}
label={"Experiences"}
/>