使用UseEffect钩子更新className

时间:2020-08-27 12:06:58

标签: reactjs react-hooks

目前,我正在练习我的React技能。现在,我正在研究我的Hooks知识。我使用了Coctail API来加载一些数据。只是为了好玩,我通过导航栏将其分为三类。

当我单击导航项时,我会进入子类别。但是我的课程不会更新,因此制表符系统不起作用。你们知道我在这里做什么?我以几种不同的方式尝试了此方法,但没有任何效果。

import React, { useState, useEffect } from 'react';
import axios from 'axios';

const OverView = () => {
  const [ term, setTerm ] = useState('Gin');
  const [ categorie, setCategorie ] = useState('Cocktail');
  const [ debouncedTerm, setDebouncedTerm ] = useState(term);
  const [ results, setResults] = useState([]);

  useEffect(() => {
    const timerId = setTimeout(() => {
      setDebouncedTerm(term);
    }, 10);

    return () =>{
      clearTimeout(timerId);
    };
  }, [term]);

  useEffect(() => {
    const search = async () => {
      const { data } = await axios({
        'method':'GET',
        'url':'https://the-cocktail-db.p.rapidapi.com/filter.php',
        'headers':{
          'content-type':'application/octet-stream',
          'x-rapidapi-host':'the-cocktail-db.p.rapidapi.com',
          'x-rapidapi-key':'49adf3a5ccmsh5d525b0005370d3p1b460bjsn7b0add17579e',
          'useQueryString':true
        },'params':{
          'i': debouncedTerm
        },
    });
    setResults(data.drinks);

    };
    search();
  }, [debouncedTerm]);

   const renderResults = results.map((result) => {
    return (
      <div key={result.idDrink} className="four wide column" style={{marginBottom:"20px"}}>
        <a href={result.idDrink}>
          <div className="card">
            <img src={result.strDrinkThumb} width="250"/>
            <div className="header">{result.strDrink}</div>
          </div>
        </a>
        </div>
    );
  });

  return (
    <div className="ui grid">
      <div className="row">
          <h3>Select your favourate drink to get started</h3>
          <div className="ui top attached tabular menu">
            <div
              className={'item active'}
              onClick={(e) => setTerm('Gin') }>
              Gin
            </div>
            <div
              className={'item'}
              onClick={(e) => setTerm('Vodka')}>
              Vodka
            </div>
            <div
              className={'item'}
              onClick={(e) => setTerm('Whiskey')}>
              Whiskey
            </div>
          </div>
        </div>
      <div className="row">
          {renderResults}
      </div>
    </div>
  );
};

export default OverView;

预先感谢。我的第一个问题是我不知道如何在我的钩子上添加额外的操作。我无法附加一个额外的onClick事件,也不知道如何将其添加到我的useEfect函数中。

1 个答案:

答案 0 :(得分:0)

基于className状态原子设置term,就这么简单。

我也重构了一些东西

  • 结果组件现在是一个单独的组件
  • 将搜索重构为一个单独的函数
import React, { useState, useEffect } from "react";
import axios from "axios";

const ResultCard = ({ result }) => (
  <div className="four wide column" style={{ marginBottom: "20px" }}>
    <a href={result.idDrink}>
      <div className="card">
        <img src={result.strDrinkThumb} width="250" />
        <div className="header">{result.strDrink}</div>
      </div>
    </a>
  </div>
);

async function doSearch(term) {
  const { data } = await axios({
    method: "GET",
    url: "https://the-cocktail-db.p.rapidapi.com/filter.php",
    headers: {
      "content-type": "application/octet-stream",
      "x-rapidapi-host": "the-cocktail-db.p.rapidapi.com",
      "x-rapidapi-key": "49adf3a5ccmsh5d525b0005370d3p1b460bjsn7b0add17579e",
      useQueryString: true,
    },
    params: {
      i: term,
    },
  });
  return data;
}

const OverView = () => {
  const terms = ["Gin", "Vodka", "Whiskey"];
  const [term, setTerm] = useState("Gin");
  const [results, setResults] = useState([]);
  useEffect(() => {
    doSearch(term).then((data) => setResults(data.drinks));
  }, [term]);

  return (
    <div className="ui grid">
      <div className="row">
        <h3>Select your favourate drink to get started</h3>
        <div className="ui top attached tabular menu">
          {terms.map((t) => (
            <div
              className={["item", term === t ? "active" : null].filter(Boolean).join(" ")}
              onClick={(e) => setTerm(t)}
            >
              {t}
            </div>
          ))}
        </div>
      </div>
      <div className="row">
        {results.map((result) => (
          <ResultCard result={result} key={result.idDrink} />
        ))}
      </div>
    </div>
  );
};

export default OverView;

您可能希望研究classnames模块;奥秘的[].filter().join()表达式将变成cx({item: true, active: t === term}):)