skip to Main Content

    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


  1. 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 just term).

    No need for that wrapper, directly pass the state setter to your context value:

    <ProductSearchTermContext.Provider
      value={[searchTerm, setSearchTerm]} // Lower case set, i.e. directly the state setter
    >
    
    Login or Signup to reply.
  2. 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.

      function SetSearchTerm(term: string) {
            setSearchTerm((oldState) => oldState + term);
      }
    

    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:

    function SetSearchTerm(term: string) {
      setSearchTerm(term); // Replace the old term with the new term
    }
    

    It will fix your duplication issue.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search