如何让一个自定义钩子等待另一个必须返回第一个钩子的输入参数的钩子



它看起来像绕口令。

情况是,我有一个自定义钩子,让我们称它为hookFather,其中的其他钩子为hookChild1hookChild2。。。我需要CCD_ 4的值,但在CCD_。并且(hookChild1hookChild2的(这两个值稍后将在hookFather中进行处理。

我怎样才能建立一个他们相互等待的结构呢。我无法将挂钩放入useEffect或useMemo

是的,hoodChild1是异步的,因为它是一个GraphQL查询。。。换言之,我怎么能像hookFather异步那样进行自定义挂钩呢?

钩子非常像组件函数。如果钩子要启动稍后将完成的操作并更新钩子管理的状态,则可以在useEffect回调中执行此操作,并使用useState跟踪状态。

下面是一个使用setTimeout代替GraphQL查询的基本示例:

function useSomething(value) {
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
const [result, setResult] = useState(null);
useEffect(() => {
// Clear result, set loading, start query
setResult(null);
setLoading(true);
setError(null);
const handle = setTimeout(() => {
// Query complete, save the result and clear the loading flag
if (Math.random() < 0.333333333333333) {
// About a third of the time, fail for demonstration purposes
setError(new Error("Failed to load stuff"));
} else {
setResult(value * 2);
}
setLoading(false);
}, 500);
// Return a cleanup callback that cancels the timer if `value`
// changes or the component using this hook is unmounted
return () => {
clearTimeout(handle);
};
}, [value]);
// Return the loading flag, error, and the current result
return [loading, error, result];
}

const {useState, useEffect} = React;
function useSomething(value) {
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
const [result, setResult] = useState(null);
useEffect(() => {
// Clear result, set loading, start query
setResult(null);
setLoading(true);
setError(null);
const handle = setTimeout(() => {
// Query complete, save the result and clear the loading flag
if (Math.random() < 0.333333333333333) {
// About a third of the time, fail for demonstration purposes
setError(new Error("Failed to load stuff"));
} else {
setResult(value * 2);
}
setLoading(false);
}, 500);
// Return a cleanup callback that cancels the timer if `value`
// changes or the component using this hook is unmounted
return () => {
clearTimeout(handle);
};
}, [value]);
// Return the loading flag, error, and the current result
return [loading, error, result];
}
const Example = () => {
const [value, setValue] = useState(1);
const [loading, error, result] = useSomething(value);
return <div>
<div>Value: {value} <input type="button" onClick={() => setValue(v => v + 1)} value="+" /></div>
<div>Result for {value}: {
loading
? <em>Loading...</em>
: error
? <strong>Error: {error.message}</strong>
: result
}</div>
</div>;
};
ReactDOM.render(<Example />, document.getElementById("root"));
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.development.js"></script>

注意它是如何返回使用它的组件所需的三条信息的:

  • 指示其异步工作正在进行的标志(loading(
  • 指示发生错误的错误值(在这种情况下,null表示无(
  • 结果数据

还有其他方法可以返回这三条信息。例如,您可以返回一个具有state("loading""error""complete"(和error(如果处于错误状态(或value(如果处于completed状态(的对象:

const {useState, useEffect} = React;
const states = {
loading: "loading",
error: "error",
success: "success",
};
function useSomething(value) {
const [state, setState] = useState({
state: states.loading,
});
useEffect(() => {
// Clear result, set loading, start query
setState({
state: states.loading,
});
const handle = setTimeout(() => {
// Query complete, save the result and clear the loading flag
if (Math.random() < 0.333333333333333) {
// About a third of the time, fail for demonstration purposes
setState({
state: states.error,
error: new Error("Failed to load stuff"),
});
} else {
setState({
state: states.success,
value: value * 2,
});
}
}, 500);
// Return a cleanup callback that cancels the timer if `value`
// changes or the component using this hook is unmounted
return () => {
clearTimeout(handle);
};
}, [value]);
// Return the state
return state;
}
const Example = () => {
const [value, setValue] = useState(1);
const something = useSomething(value);
return <div>
<div>Value: {value} <input type="button" onClick={() => setValue(v => v + 1)} value="+" /></div>
<div>Result for {value}: {
something.state === "loading"
? <em>Loading...</em>
: something.state === "error"
? <strong>Error: {something.error.message}</strong>
: something.value
}</div>
</div>;
};
ReactDOM.render(<Example />, document.getElementById("root"));
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.development.js"></script>

但基本情况仍然相同:钩子至少有三种状态:Loading、Error和Success。

相关内容

  • 没有找到相关文章

最新更新