import React, { createContext, useContext, useState } from "react";
export const ProductSearchTermContext = createContext(["", undefined]);
function ProductSearchTermContextProvider() {
const [searchTerm, setSearchTerm] = useState("");
function SetSearchTerm(term: string) {
setSearchTerm((oldState) => oldState + term);
}
return (
<ProductSearchTermContext.Provider value={[searchTerm, SetSearchTerm]}>
{children}
</ProductSearchTermContext.Provider>
);
}
export default function Input() {
const [searchTerm, setSearchTerm] = useContext(ProductSearchTermContext);
const onChange = (e: any) => {
e.preventDefault();
setSearchTerm!(e.target.value);
};
return <input value={searchTerm} onChange={onChange} />;
}
export default function App() {
return (
<ProductSearchTermContextProvider>
<Input />
</ProductSearchTermContextProvider>
);
}
I have a simple context that passes useState
‘s getter and setter to an input
field to display and set the state’s value. Unfortunately, the data is duplicating, and when I type "abcd" I get "aabaabcaabaabcd".
Here is the SandBox link.
2
Answers
The
<input>
value is the entire content shown in UI, not just the last stroke key.Therefore the
SetSearchTerm
wrapper function concatenates too much data (oldState + term
, instead of justterm
).No need for that wrapper, directly pass the state setter to your context value:
The issue with the SetSearchTerm function in your code is that you’re appending the new term to the previous searchTerm value rather than replacing it.
it takes the old state (oldState) and concatenates the new term (term) to it. This causes the search term to duplicate or append on every input change.
To fix the issue, modify the SetSearchTerm function to simply update the state with the new term, rather than concatenating it:
It will fix your duplication issue.