React implements a search function

  • Real-time search is required to get results, which are returned by interface data
  • Realize the figure

Let’s start with a basic react implementation

import stores from './stores' // Prepared interface library
import _ from 'loadsh'; // Use debounce to get the interface in real time

class Search extend Component{
    featchList = async (val = ' ') = > {try{
            const data = await stores.featchList(val);
            
            data && this.setState({
                data
            })
        }catch(err){
            throw(err)
        }
    }

    handleOnSearch = (ev) = >{
        console.log(ev);
        
        this.featchList(ev.target.value)
    }
    
    componentDidMount(){
        this.featchList();
    }
    
    render(){
        <div className="search-container">
            <input onChange={_.debounce(ev= > this.handleOnSearch(ev), 300)}/>
            <div className="list">
                {this.state.data}
            </div>
        </div>}}Copy the code

React: do a simple search in real time and display the result in 300ms delay. Use hooks to modify react.

The little knowledge useEffect

  • useEffect(cakkBackFunc, array)
CakkBackFunc can return a function used to clean array (optional) : array, used to control useEffect execution * There are three cases.1"ComponentDidMount" (first render)2UseEffect is executed after the array changes.3UseEffect is executed every time you render an arrayCopy the code

Hooks reality search function

function App() {
  const [data, setData] = useState([]);
  const [query, setQuery] = useState(' ');

  useEffect((a)= > {
    const featchList = async (query = ' ') = > {try{
            const data = await stores.featchList(query);
            
            data && setData(data);
        }catch(err){
            throw err;
        }
    }

    featchList(query); // We pass query as a parameter, and link data with query to achieve the search function.} []);return (
    <div className="search-container">
        <input onChange={_.debounce(ev= > setQuery(ev.target.value), 300)}/>
        <div className="list">
            {this.state.data}
        </div>
    </div>
  );
}

export default App;
Copy the code
  • React generates a warning for the following plugins

React Hook useEffect has a missing dependency: 'featchList'. Either include it or remove the dependency array

We provided one`exhaustive-deps ESLint`Rules as`eslint-plugin-react-hooks`Part of the bag. It will help you identify components that are not handling updates consistently.Copy the code

For componentDidMount, we’re only getting data once. We’re not asking for new data when we enter the input box. Add [query] to the second parameter of useEffect(a,b) and refire useEffect() when it changes.

function App() {
  const [data, setData] = useState([]);
  const [query, setQuery] = useState(' ');

  useEffect((a)= > {
    const featchList = async (query = ' ') = > {try{
            const data = await stores.featchList(query);
            
            data && setData(data);
        }catch(err){
            throw err;
        }
    }

    featchList(query); // We pass query as a parameter, and link data with query to achieve the search function.
  }, [query]); // As query changes, remount to retrieve the new search data

  return(...). ; }export default App;
Copy the code

A derivative question? Is it safe to omit functions from the dependency list?

  • Why do we define featchList inside useEffect()? What difference does it make if I just write it out like I did before?

  • If you specify a dependency list as the last parameter to useEffect, useMemo, useCallback, or useImperativeHandle, it must contain all the values participating in the React data stream. This includes props, state, and anything derived from them. = =

function ProductPage({ productId }) {
  const [product, setProduct] = useState(null);

  async function fetchProduct() {
    const response = await fetch('http://myapi/product' + productId); // 使用了 productId prop
    const json = await response.json();
    setProduct(json);
  }

  useEffect((a)= >{ fetchProduct(); } []);// 🔴 this is invalid because 'fetchProduct' uses' productId '
  // ...
}
Copy the code
  • Solution: The recommended fix is to move the function inside your effect. This makes it easy to see which props and states your effect uses
function ProductPage({ productId }) {
  const [product, setProduct] = useState(null);

  useEffect((a)= > {
    // After moving this function inside effect, we can clearly see the value it uses.
    async function fetchProduct() {
      const response = await fetch('http://myapi/product' + productId);
      const json = await response.json();
      setProduct(json);
    }

    fetchProduct();
  }, [productId]); // ✅ works because we only use productId for effect
  // ...
}
Copy the code

To sum up, if we use props,state, or their derived values, we need to put the related function in useEffect, and then put the related value in the second parameter of useEffect

reference

  • Segmentfault.com/a/119000001…
  • Codesandbox. IO/s/jvvkoo8pq… (Official implementation demo)
  • www.cnblogs.com/tengfeiS/p/…