为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

开心每一天1111 2023-03-03 18:56:25
所以基本上感谢 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”,而我希望它根据指定的秒数翻转。我错过了什么?
查看完整描述

3 回答

?
月关宝盒

TA贡献1772条经验 获得超5个赞

让您的组件在索引更改时由其状态驱动,它会触发更新 currentFruit 状态的 useEffect 挂钩,currentFruit 更改会触发另一个更新索引的 useEffect 等等,然后只需使用 like setTimeout:


const IntervalExample = () => {

    const fruits = [

        {id: 1, name: "Orange", duration: 2000},

        {id: 2, name: "Kiwi", duration: 1000},

        {id: 3, name: "Mango", duration: 3000},

    ]


    const [index, setIndex] = useState(0);

    const [currentFruit, setCurrentFruit] = useState(fruits[index]);


   

    

    useEffect(() => {

        setCurrentFruit(fruits[index])

    }, [index])


    useEffect(() => {

        const interval = setTimeout(() => {

            setIndex(index === fruits.length - 1 ? 0 : index + 1)       

        }, currentFruit.duration);

    }, [currentFruit])


    return (

        <div className="App">

            <header className="App-header">

                {currentFruit.name}: {currentFruit.duration}

            </header>

        </div>

    );

};


查看完整回答
反对 回复 2023-03-03
?
慕虎7371278

TA贡献1802条经验 获得超4个赞

UseEffect 只被调用一次。因此,Const interval将为时间间隔的函数调用初始化一个闭包。它永远不会改变。关闭中的索引将始终为 0。


这是我的解决方案,只需使用一种状态作为索引:


const IntervalExample = () => {

    const fruits = [

        {id: 1, name: "Orange", duration: 2000},

        {id: 2, name: "Kiwi", duration: 1000},

        {id: 3, name: "Mango", duration: 3000},

    ]


    const [index, setIndex] = useState(0);


    //because fruit depend on index. Dont need a separate state

    const currentFruit = fruits[index];


    const handleIndex = () => {

        setIndex(index === fruits.length - 1 ? 0 : index + 1)

    }


    useEffect(() => {

        //after render current fruit. We new timeout to set next fruit.

        setTimeout(handleIndex, currentFruit.duration);

    }, [index]);


    return (

        <div className="App">

            <header className="App-header">

                {currentFruit.name}: {currentFruit.duration}

            </header>

        </div>

    );

};


查看完整回答
反对 回复 2023-03-03
?
慕的地8271018

TA贡献1796条经验 获得超4个赞

如果你想为每个水果使用不同的超时,那setTimeout将是更好的方法。


由于在初始值setInterval被调用时会被设置为改变显示水果信息的时间间隔。useEffect


您的代码中的问题是在更新index状态时未正确更新。


为了解决这个问题而不是直接更新值,我使用更新后的状态值,如下所示


setIndex((index) => (index === fruits.length - 1 ? 0 : index + 1))

const { useState, useEffect } = React;


const fruits = [

  { id: 1, name: "Orange", duration: 2000 },

  { id: 2, name: "Kiwi", duration: 1000 },

  { id: 3, name: "Mango", duration: 3000 }

];


const IntervalExample = () => {

  const [index, setIndex] = useState(0);

  const [currentFruit, setCurrentFruit] = useState(fruits[0]);


  useEffect(() => {

    const interval = setInterval(() => {

      setIndex((index) => (index === fruits.length - 1 ? 0 : index + 1));

    }, fruits[index].duration);

    return () => clearInterval(interval);

  }, []);


  useEffect(() => {

    setCurrentFruit(fruits[index]);

  }, [index]);


  return (

    <div className="App">

      <header className="App-header">

        {currentFruit.name}: {currentFruit.duration}

      </header>

    </div>

  );

};



ReactDOM.render(

       <IntervalExample />,

       document.getElementById("root")

     );

<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>


查看完整回答
反对 回复 2023-03-03
  • 3 回答
  • 0 关注
  • 160 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信