首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么使用useEffect使代码呈现两次?还是延迟?

为什么使用useEffect使代码呈现两次?还是延迟?
EN

Stack Overflow用户
提问于 2022-01-31 06:28:12
回答 1查看 65关注 0票数 0

鼓垫组件

代码语言:javascript
复制
import PubSub from 'pubsub-js';
import React,{useState,useEffect,useRef} from 'react';
import {bankOne,bankTwo} from './Bank.js';
import './Drumpad.scss';

const Drumpad = () =>{
  const [bank,setBank] = useState(bankOne);
  const [isPowered, setIsPowered] = useState(false);
  const [soundName, setSoundName] = useState("");
  useEffect(
    ()=>{
      const mySub = PubSub.subscribe('changeBank',chooseBank);
      const mySecondSub = PubSub.subscribe('powerStatus',changePowerStatus);
      return () => {
        PubSub.unsubscribe(mySub);
        PubSub.unsubscribe(mySecondSub);
      };
    },[]
  );
  document.addEventListener('keydown', handleKeyPress);
  const chooseBank = (changeBank,{bankName}) => {
    bankName === 'Heater 1' ? setBank(bankOne) : setBank(bankTwo);
  };
  console.log(isPowered);
  const changePowerStatus = (powerStatus,{isOn}) =>{
    setIsPowered (isOn);
  }

  const handleClick = (event) => {
    if(isPowered){
      const audio = event.target.children[0];
      audio.play();
      audio.currentTime=0;
      const name = event.target.id;
      setSoundName(name);
      pubInfo();
    }
  };

  function handleKeyPress(event) {
    const key = event.key.toUpperCase();
    console.log(isPowered);
    if ("QWEASDZXC".includes(key) && isPowered) {
          document.getElementById(key).play();
          document.getElementById(key).currentTime = 0;
          const name = document.getElementById(key).parentElement.id;
          setSoundName(name);
          pubInfo();
     };
  };

  const pubInfo = () =>{
    PubSub.publish("updateInfo",{soundName});
  }

  return bank.map(sound =>{
    return <li key={sound.keyTrigger} className="Key">
             <button className="drum-pad" id={sound.id} onClick={handleClick}>
              <audio className="clip" id={sound.keyTrigger} src={sound.url}/>
              {sound.keyTrigger}
            </button>
            </li>
  })
}

export default Drumpad;

DrumControl组件

代码语言:javascript
复制
import PubSub from 'pubsub-js';
import React,{useState,useEffect} from 'react';
import './DrumControl.scss';
import { Switch } from 'antd';
import 'antd/dist/antd.css';

const DrumControl = () => {
  const [isOn,setIsOn] = useState(false);
  const [bankName,setBankName] = useState("Heater 1");
  const [info,setInfo] = useState("");

  useEffect(
    ()=> {
      pubPower();
      const myInfo = PubSub.subscribe("updateInfo",soundNameUpdate);
      return () => {
        PubSub.unsubscribe(myInfo);
      };
    }
  );

  const soundNameUpdate = (updateInfo,{soundName}) =>{
    setInfo(soundName);
  }

  const onOff = () =>{
    isOn ? setIsOn(false) : setIsOn(true);
    setInfo("");
  }

  const changeBankName = ()=>{
      bankName === "Heater 1" ? setBankName("Piano") : setBankName("Heater 1");
      setInfo(bankName);
      pubBank();
  }

  const pubBank = () =>{
    PubSub.publish('changeBank',{bankName});
  }

  const pubPower = () =>{
    PubSub.publish('powerStatus',{isOn});
  }

  const onclick = () =>{
    isOn ? changeBankName() : setInfo("");
  }

  return (
    <div className="drum-control">
      <header>
        <a className="navbar-brand text-dark" href="#">
        Sean Liu
        </a>
      </header>
      <p className="text-dark fw-bold">Power</p>
      <Switch onClick={onOff}/>
      <p id="display">{info}</p>

      <input type="range" className="form-range" min="0" max="100" id="volume-control"/>

      <p className="text-dark fw-bold">Bank</p>
      <Switch onClick={onclick}/>
    </div>
  );
}

export default DrumControl;

App.js

代码语言:javascript
复制
import './App.scss';
import DrumControl from './components/DrumControl';
import Drumpad from './components/Drumpad';
function App() {
  return (
    <div className="App">
      <div className="App-content" id="drum-machine">
        <div className="drum-keys">
          <Drumpad />
        </div>
        <DrumControl />
      </div>
    </div>
  );
}

export default App;

嗨,专家们,我刚开始编程,试着用反应钩来构建一个鼓式机器项目,现在我觉得我被困在的地方是useEffect reRender问题。当我切换开关按钮时,console.log(isPowered)执行两次,而且我还必须按两次键才能使myInfo执行和更新setInfo,请帮助我完成此操作。

EN

回答 1

Stack Overflow用户

发布于 2022-01-31 07:04:11

您可以使用useCallback钩子来限制它;例如,我与您共享:

代码语言:javascript
复制
 const [articles, setArticles] = useState([]);
  const [loading, setLoading] = useState(false);
  // const [page, setPage] = useState(0);
  let url = "https://newsapi.org/v2/top-headlines?country="in"&category="general"&apiKey"
  const fetchData = useCallback(async () => {
    try {
      setLoading(true);
      const response = await fetch(url);
      const json = await response.json();
      setArticles(json.articles);
    } catch (error) {
      throw error;
    } finally {
      setLoading(false);
    }
  }, [url]);

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70922001

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档