最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - React how to run a function only once, after page enter or refresh - Stack Overflow

programmeradmin7浏览0评论

I'm working on a search function with algolia search. The user may put in a search term from a different site, get redirected to the search page, and the search should be invoked.

After this, to search for more stuff, the user need to use the search bar in the search page, and hit enter to invoke the search again.

I've tried to use a useState and set it to true after the first render. However when I type in my search bar, the useEffect gets invoked at every key press. Why is this happening when firstRender doesn't change? It will set firstRender to true again, but since firstRender already is true, nothing should happen?

How can I "deactivate" the useEffect after the first render, so that the user only uses the search bar to search?

(I don't want to hammer the API with requests while the user is typing)

Thanks!

const SearchRecipes = () => {
  const client = algoliasearch(process.env.REACT_APP_ALGOLIA_APP_ID, process.env.REACT_APP_ALGOLIA_SEARCH_API);
  const index = client.initIndex('recipe_search');
  const match = useRouteMatch();
  const [searchTerm, setSearchTerm] = useState(match.params.id);
  const [searchReturnData, setSearchReturnData] = useState([]);
  const [firstRender, setFirstRender] = useState(false);
  const useMountEffect = (fun) => useEffect(fun, [])


  useEffect(() => {
    handleSubmit();
    setFirstRender(true);
  }, [firstRender])

  const handleSubmit = (e = null) => {
    if (e !== null){
      e.preventDefault();
    }

    index
      .search(searchTerm)
      .then((responses) => {
        setSearchReturnData(responses.hits);
      });
  }

  return (
    // irrelevant JSX
   <div className="keywords">
     <input 
       type="text" 
       value={searchTerm}
       onChange={({target}) => setSearchTerm(target.value)}
     />
   </div>
   // more irrelevant JSX
  )
} 

I'm working on a search function with algolia search. The user may put in a search term from a different site, get redirected to the search page, and the search should be invoked.

After this, to search for more stuff, the user need to use the search bar in the search page, and hit enter to invoke the search again.

I've tried to use a useState and set it to true after the first render. However when I type in my search bar, the useEffect gets invoked at every key press. Why is this happening when firstRender doesn't change? It will set firstRender to true again, but since firstRender already is true, nothing should happen?

How can I "deactivate" the useEffect after the first render, so that the user only uses the search bar to search?

(I don't want to hammer the API with requests while the user is typing)

Thanks!

const SearchRecipes = () => {
  const client = algoliasearch(process.env.REACT_APP_ALGOLIA_APP_ID, process.env.REACT_APP_ALGOLIA_SEARCH_API);
  const index = client.initIndex('recipe_search');
  const match = useRouteMatch();
  const [searchTerm, setSearchTerm] = useState(match.params.id);
  const [searchReturnData, setSearchReturnData] = useState([]);
  const [firstRender, setFirstRender] = useState(false);
  const useMountEffect = (fun) => useEffect(fun, [])


  useEffect(() => {
    handleSubmit();
    setFirstRender(true);
  }, [firstRender])

  const handleSubmit = (e = null) => {
    if (e !== null){
      e.preventDefault();
    }

    index
      .search(searchTerm)
      .then((responses) => {
        setSearchReturnData(responses.hits);
      });
  }

  return (
    // irrelevant JSX
   <div className="keywords">
     <input 
       type="text" 
       value={searchTerm}
       onChange={({target}) => setSearchTerm(target.value)}
     />
   </div>
   // more irrelevant JSX
  )
} 
Share Improve this question asked Jul 28, 2020 at 4:43 Stephan Bakkelund ValoisStephan Bakkelund Valois 1,0722 gold badges13 silver badges25 bronze badges 1
  • 1 Trye UseEffect(()=>{//your code},[]), it will be invoked only for the first render – Asutosh Commented Jul 28, 2020 at 4:46
Add a ment  | 

1 Answer 1

Reset to default 4

The reason is that your useEffect has a dependency on firstRender and inside it it is setting that value.

You could either follow the suggestion from the ment, using an empty array of dependencies:

useEffect(() => {
  handleSubmit();
}, [])

or check if your firstRender state is already set:

useEffect(() => {
  if (!firstRender) {
    handleSubmit();
    setFirstRender(true);
  }
}, [firstRender])

This is a really nice article about useEffect if you need more info.

发布评论

评论列表(0)

  1. 暂无评论