Reactjs 单击选项卡不会';t重新启动内部运行的函数

Reactjs 单击选项卡不会';t重新启动内部运行的函数,reactjs,material-ui,Reactjs,Material Ui,我正在使用Materal UI的选项卡,我遇到了一个问题,每次单击选项卡时,它都不会从一开始就开始执行功能。相反,所有功能都在所有选项卡中同时完成,这不是我所需要的。我如何更改它,以便当我单击该选项卡时,它从一开始就开始执行其中的函数 我在下面的codesandbox中举例说明了我的意思,显示了3个选项卡,计时器为5秒,其中选项卡中的所有功能都是同时执行的,这不是所需的,单击选项卡不会重新启动它 代码沙盒代码: 功能选项卡面板(道具){ const{children,value,index,…o

我正在使用Materal UI的选项卡,我遇到了一个问题,每次单击选项卡时,它都不会从一开始就开始执行功能。相反,所有功能都在所有选项卡中同时完成,这不是我所需要的。我如何更改它,以便当我单击该选项卡时,它从一开始就开始执行其中的函数

我在下面的codesandbox中举例说明了我的意思,显示了3个选项卡,计时器为5秒,其中选项卡中的所有功能都是同时执行的,这不是所需的,单击选项卡不会重新启动它

代码沙盒代码:

功能选项卡面板(道具){
const{children,value,index,…other}=props;
返回(
{value===索引&&(
{儿童}
)}
);
}
TabPanel.propTypes={
子项:PropTypes.node,
索引:PropTypes.any.isRequired,
值:PropTypes.any.isRequired
};
功能a11yProps(索引){
返回{
id:`simple tab-${index}`,
“aria控件”:`简单选项卡面板-${index}`
};
}
const useStyles=makeStyles((主题)=>({
根目录:{
flexGrow:1,
背景色:theme.palete.background.paper
}
}));
导出默认函数SimpleTabs(){
const classes=useStyles();
const[value,setValue]=React.useState(0);
const[text1,setText1]=React.useState(“Wait 1”);
const[text2,setText2]=React.useState(“Wait 2”);
const[text3,setText3]=React.useState(“Wait 3”);
常量handleChange=(事件,newValue)=>{
设置值(新值);
};
//
函数tab1(){
setTimeout(函数(){
setText1(“完成1”);
}, 5000);
}
//
函数tab2(){
setTimeout(函数(){
setText2(“完成2”);
}, 5000);
}
//
函数tab3(){
setTimeout(函数(){
setText3(“完成3”);
}, 5000);
}
返回(
{text1}
{tab1()}
{text2}
{tab2()}
{text3}
{tab3()}
);
}
问题
  • 在“render”函数return中,状态更新是一个副作用,返回应该是纯的
  • 所有选项卡面板同时安装,并保持安装状态
  • 您不会对选项卡索引的更改做出反应,因此不会重新运行任何函数
  • 解决方案
  • 使用
    useffect
    hook“重新启动”回调
  • 每个回调都应该“重置”状态
  • 保存超时参考,以便在重置时清除任何正在运行的计时器
  • 更新组件

    export default function SimpleTabs() {
      const classes = useStyles();
      const [value, setValue] = useState(0);
      const [text1, setText1] = useState("Wait 1");
      const [text2, setText2] = useState("Wait 2");
      const [text3, setText3] = useState("Wait 3");
    
      const timer1Ref = useRef();
      const timer2Ref = useRef();
      const timer3Ref = useRef();
    
      const handleChange = (event, newValue) => {
        setValue(newValue);
      };
    
      useEffect(() => {
        switch (value) { // <-- invoke specific callback associated with tab
          case 0:
            tab1();
            break;
    
          case 1:
            tab2();
            break;
    
          case 2:
            tab3();
            break;
    
          default:
          // ignore
        }
      }, [value]); // <-- trigger when tab index value updates
    
      function tab1() {
        clearTimeout(timer1Ref.current);
        setText1("Wait 1"); // <-- reset state
        timer1Ref.current = setTimeout(function () {
          setText1("Done 1");
        }, 5000);
      }
    
      function tab2() {
        clearTimeout(timer2Ref.current);
        setText2("Wait 2");
        timer2Ref.current = setTimeout(function () {
          setText2("Done 2");
        }, 5000);
      }
    
      function tab3() {
        clearTimeout(timer3Ref.current);
        setText3("Wait 3");
        timer3Ref.current = setTimeout(function () {
          setText3("Done 3");
        }, 5000);
      }
    
      return (
        <div className={classes.root}>
          <AppBar position="static">
            <Tabs
              value={value}
              onChange={handleChange}
              aria-label="simple tabs example"
            >
              <Tab label="Item One" {...a11yProps(0)} />
              <Tab label="Item Two" {...a11yProps(1)} />
              <Tab label="Item Three" {...a11yProps(2)} />
            </Tabs>
          </AppBar>
          <TabPanel value={value} index={0}>
            {text1}
            {/* {tab1()} */} // <-- Don't update state from return!!
          </TabPanel>
          <TabPanel value={value} index={1}>
            {text2}
            {/* {tab2()} */}
          </TabPanel>
          <TabPanel value={value} index={2}>
            {text3}
            {/* {tab3()} */}
          </TabPanel>
        </div>
      );
    }
    
    导出默认函数SimpleTabs(){
    const classes=useStyles();
    const[value,setValue]=useState(0);
    const[text1,setText1]=useState(“等待1”);
    const[text2,setText2]=useState(“等待2”);
    const[text3,setText3]=useState(“等待3”);
    常量timer1Ref=useRef();
    常量timer2Ref=useRef();
    常量timer3Ref=useRef();
    常量handleChange=(事件,newValue)=>{
    设置值(新值);
    };
    useffect(()=>{
    
    切换(值){//为什么渲染返回会产生副作用以更新状态?所有选项卡面板同时安装,因此函数
    tab1
    tab2
    、和
    tab3
    都或多或少“同时”运行。是否需要特定的
    选项卡[1 | 2 | 3]
    函数在活动选项卡索引更改时运行?基本上,我希望它在单击选项卡时刷新其中包含的所有内容,就像单击抽屉中的按钮时一样,它刷新了该选项卡,因此在我的示例中,当我单击任何选项卡时,我应该看到等待1,2,3,然后在5秒后显示完成,我不等待单击任何选项卡选项卡并查看它是否已完成执行
    export default function SimpleTabs() {
      const classes = useStyles();
      const [value, setValue] = useState(0);
      const [text1, setText1] = useState("Wait 1");
      const [text2, setText2] = useState("Wait 2");
      const [text3, setText3] = useState("Wait 3");
    
      const timer1Ref = useRef();
      const timer2Ref = useRef();
      const timer3Ref = useRef();
    
      const handleChange = (event, newValue) => {
        setValue(newValue);
      };
    
      useEffect(() => {
        switch (value) { // <-- invoke specific callback associated with tab
          case 0:
            tab1();
            break;
    
          case 1:
            tab2();
            break;
    
          case 2:
            tab3();
            break;
    
          default:
          // ignore
        }
      }, [value]); // <-- trigger when tab index value updates
    
      function tab1() {
        clearTimeout(timer1Ref.current);
        setText1("Wait 1"); // <-- reset state
        timer1Ref.current = setTimeout(function () {
          setText1("Done 1");
        }, 5000);
      }
    
      function tab2() {
        clearTimeout(timer2Ref.current);
        setText2("Wait 2");
        timer2Ref.current = setTimeout(function () {
          setText2("Done 2");
        }, 5000);
      }
    
      function tab3() {
        clearTimeout(timer3Ref.current);
        setText3("Wait 3");
        timer3Ref.current = setTimeout(function () {
          setText3("Done 3");
        }, 5000);
      }
    
      return (
        <div className={classes.root}>
          <AppBar position="static">
            <Tabs
              value={value}
              onChange={handleChange}
              aria-label="simple tabs example"
            >
              <Tab label="Item One" {...a11yProps(0)} />
              <Tab label="Item Two" {...a11yProps(1)} />
              <Tab label="Item Three" {...a11yProps(2)} />
            </Tabs>
          </AppBar>
          <TabPanel value={value} index={0}>
            {text1}
            {/* {tab1()} */} // <-- Don't update state from return!!
          </TabPanel>
          <TabPanel value={value} index={1}>
            {text2}
            {/* {tab2()} */}
          </TabPanel>
          <TabPanel value={value} index={2}>
            {text3}
            {/* {tab3()} */}
          </TabPanel>
        </div>
      );
    }