I just put together a small demo of one way you can do this. It may not be the cleanest solution, but it should be enough to work from.
https://codesandbox.io/s/exciting-nobel-ul3r5?file=/src/App.js
The idea is you have an array of values held on your parent component that holds whether or not each child is performing an action. I have a timer set on both to finish at different times.
You can only run the test if none of the children are currently running their action.
I'd need more information about your requirements to be able to give anymore advice. There are many ways to do this and it's always going to be dependent on your specific needs.
import React, { Fragment, useEffect, useState } from "react";
export default function App() {
const [isTesting, setIsTesting] = useState([false, false]);
const setChildTesting = (index) => (value) =>
setIsTesting((isTesting) => {
const result = [...isTesting];
result[index] = value;
return result;
});
return (
<div>
<button
onClick={() => setIsTesting([true, true])}
disabled={isTesting.some((e) => e)}
>
Run Test
</button>
<br />
<Child1 isTesting={isTesting[0]} setIsTesting={setChildTesting(0)} />{" "}
{isTesting[0] && "(running)"}
<br />
<Child2 isTesting={isTesting[1]} setIsTesting={setChildTesting(1)} />{" "}
{isTesting[1] && "(running)"}
</div>
);
}
function Child1({ isTesting, setIsTesting }) {
const [result, setResult] = useState(0);
useEffect(() => {
if (isTesting) {
const interval = setInterval(() => {
setResult((result) => result + 10);
setIsTesting(false);
}, 1000);
return () => clearInterval(interval);
}
}, [isTesting, setResult, setIsTesting]);
return <Fragment>Result: {result}</Fragment>;
}
function Child2({ isTesting, setIsTesting }) {
const [result, setResult] = useState(0);
useEffect(() => {
if (isTesting) {
const interval = setInterval(() => {
setResult((result) => result + 1);
setIsTesting(false);
}, 2000);
return () => clearInterval(interval);
}
}, [isTesting, setResult, setIsTesting]);
return <Fragment>Result: {result}</Fragment>;
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…