使用 React hooks 每 X 秒显示一个不同的值

所以基本上感谢 Mateo 的指点,我能够使用这个脚本更新项目元数据:


function alex_test_function() {

 // get existing oauth token

 var theAccessTkn = ScriptApp.getOAuthToken();

 // get existing project metadata

 var response = 

 UrlFetchApp.fetch('https://compute.googleapis.com/compute/v1/projects/myProject', {

   headers: {

     Authorization: 'Bearer ' + theAccessTkn

   }

 });

 var data = JSON.parse(response.getContentText());

 var metadata = data.commonInstanceMetadata


 fingerprint = metadata.fingerprint;

 new_metadata_items = metadata.items;


// update metadata

 var timestamp = new Date().getTime()

 setMetaKey(new_metadata_items, Session.getActiveUser().getEmail().split("@")[0], timestamp)


 var formData = {

  'fingerprint': fingerprint,

  'items': new_metadata_items

  };


 var postresponse = UrlFetchApp.fetch("https://compute.googleapis.com/compute/v1/projects/myProject/setCommonInstanceMetadata", {

  'method' : 'post',

  'contentType': 'application/json',

  'payload' : JSON.stringify(formData),

  'headers': {

    Authorization: 'Bearer ' + theAccessTkn

   }

  });

}


function setMetaKey(metadata, key, value){

  // Function to add metadata or update if exists

  for (var i = 0; i < metadata.length; i++) {

    if (metadata[i].key === key) {

      metadata[i].value = value;

      return;

    }

  }

  metadata.push({key:key, value:value});

}

一些陷阱,我们需要将 OAuth 范围设置为 AppScript 清单


{

  "timeZone": "America/New_York",

  "dependencies": {

  },

  "exceptionLogging": "STACKDRIVER",

  "runtimeVersion": "V8",

  "oauthScopes": [

    "https://www.googleapis.com/auth/userinfo.email", 

    "https://www.googleapis.com/auth/compute", 

    "https://www.googleapis.com/auth/script.external_request"]

}

并且运行脚本的用户需要具有编辑 GCP 项目中的项目元数据的权限。


我没有对范围进行很多实验,可以用更窄的范围而不是https://www.googleapis.com/auth/compute来执行脚本我想显示“Orange”2 秒,“Kiwi”或 1 秒,“Mango”3 秒。这是我的尝试,它显示静止的“橙色:2000”,而我希望它根据指定的秒数翻转。我错过了什么?


开心每一天1111
浏览 162回答 3
3回答

月关宝盒

让您的组件在索引更改时由其状态驱动,它会触发更新 currentFruit 状态的 useEffect 挂钩,currentFruit 更改会触发另一个更新索引的 useEffect 等等,然后只需使用 like setTimeout:const IntervalExample = () => {&nbsp; &nbsp; const fruits = [&nbsp; &nbsp; &nbsp; &nbsp; {id: 1, name: "Orange", duration: 2000},&nbsp; &nbsp; &nbsp; &nbsp; {id: 2, name: "Kiwi", duration: 1000},&nbsp; &nbsp; &nbsp; &nbsp; {id: 3, name: "Mango", duration: 3000},&nbsp; &nbsp; ]&nbsp; &nbsp; const [index, setIndex] = useState(0);&nbsp; &nbsp; const [currentFruit, setCurrentFruit] = useState(fruits[index]);&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; useEffect(() => {&nbsp; &nbsp; &nbsp; &nbsp; setCurrentFruit(fruits[index])&nbsp; &nbsp; }, [index])&nbsp; &nbsp; useEffect(() => {&nbsp; &nbsp; &nbsp; &nbsp; const interval = setTimeout(() => {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; setIndex(index === fruits.length - 1 ? 0 : index + 1)&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; }, currentFruit.duration);&nbsp; &nbsp; }, [currentFruit])&nbsp; &nbsp; return (&nbsp; &nbsp; &nbsp; &nbsp; <div className="App">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <header className="App-header">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {currentFruit.name}: {currentFruit.duration}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </header>&nbsp; &nbsp; &nbsp; &nbsp; </div>&nbsp; &nbsp; );};

慕虎7371278

UseEffect 只被调用一次。因此,Const interval将为时间间隔的函数调用初始化一个闭包。它永远不会改变。关闭中的索引将始终为 0。这是我的解决方案,只需使用一种状态作为索引:const IntervalExample = () => {&nbsp; &nbsp; const fruits = [&nbsp; &nbsp; &nbsp; &nbsp; {id: 1, name: "Orange", duration: 2000},&nbsp; &nbsp; &nbsp; &nbsp; {id: 2, name: "Kiwi", duration: 1000},&nbsp; &nbsp; &nbsp; &nbsp; {id: 3, name: "Mango", duration: 3000},&nbsp; &nbsp; ]&nbsp; &nbsp; const [index, setIndex] = useState(0);&nbsp; &nbsp; //because fruit depend on index. Dont need a separate state&nbsp; &nbsp; const currentFruit = fruits[index];&nbsp; &nbsp; const handleIndex = () => {&nbsp; &nbsp; &nbsp; &nbsp; setIndex(index === fruits.length - 1 ? 0 : index + 1)&nbsp; &nbsp; }&nbsp; &nbsp; useEffect(() => {&nbsp; &nbsp; &nbsp; &nbsp; //after render current fruit. We new timeout to set next fruit.&nbsp; &nbsp; &nbsp; &nbsp; setTimeout(handleIndex, currentFruit.duration);&nbsp; &nbsp; }, [index]);&nbsp; &nbsp; return (&nbsp; &nbsp; &nbsp; &nbsp; <div className="App">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <header className="App-header">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {currentFruit.name}: {currentFruit.duration}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </header>&nbsp; &nbsp; &nbsp; &nbsp; </div>&nbsp; &nbsp; );};

慕的地8271018

如果你想为每个水果使用不同的超时,那setTimeout将是更好的方法。由于在初始值setInterval被调用时会被设置为改变显示水果信息的时间间隔。useEffect您的代码中的问题是在更新index状态时未正确更新。为了解决这个问题而不是直接更新值,我使用更新后的状态值,如下所示setIndex((index) => (index === fruits.length - 1 ? 0 : index + 1))const { useState, useEffect } = React;const fruits = [&nbsp; { id: 1, name: "Orange", duration: 2000 },&nbsp; { id: 2, name: "Kiwi", duration: 1000 },&nbsp; { id: 3, name: "Mango", duration: 3000 }];const IntervalExample = () => {&nbsp; const [index, setIndex] = useState(0);&nbsp; const [currentFruit, setCurrentFruit] = useState(fruits[0]);&nbsp; useEffect(() => {&nbsp; &nbsp; const interval = setInterval(() => {&nbsp; &nbsp; &nbsp; setIndex((index) => (index === fruits.length - 1 ? 0 : index + 1));&nbsp; &nbsp; }, fruits[index].duration);&nbsp; &nbsp; return () => clearInterval(interval);&nbsp; }, []);&nbsp; useEffect(() => {&nbsp; &nbsp; setCurrentFruit(fruits[index]);&nbsp; }, [index]);&nbsp; return (&nbsp; &nbsp; <div className="App">&nbsp; &nbsp; &nbsp; <header className="App-header">&nbsp; &nbsp; &nbsp; &nbsp; {currentFruit.name}: {currentFruit.duration}&nbsp; &nbsp; &nbsp; </header>&nbsp; &nbsp; </div>&nbsp; );};ReactDOM.render(&nbsp; &nbsp; &nbsp; &nbsp;<IntervalExample />,&nbsp; &nbsp; &nbsp; &nbsp;document.getElementById("root")&nbsp; &nbsp; &nbsp;);<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script><div id="root"></div>
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript