【问题标题】:Is it possible to call useCallback inside another callback是否可以在另一个回调中调用 useCallback
【发布时间】:2020-12-15 04:17:49
【问题描述】:

在组件 A 中:

 const getOnClick = useCallback(
    (rec: GenericRec): (() => void) => () => {
      setSelectedRecord(rec);
    },
    [],
  );

在 A 的子组件 B 中:

const openRecord = useCallback(
    (row: Row<Record>) => () => {
      getOnClick({ id: row.original.id, name: row.original.name });
    },
    [getOnClick],
  );

getOnClick 未被调用

【问题讨论】:

  • “是否可以在另一个回调中调用 useCallback” 除非那个回调是钩子或组件。不过没关系,你没有在回调中使用useCallback
  • 从另一个函数调用你用useCallback记忆的函数就可以了。请使用 minimal reproducible example 来更新您的问题,以展示问题,最好是使用 Stack Snippets([&lt;&gt;] 工具栏按钮)的 runnable 问题。 Stack Snippets 支持 React,包括 JSX; here's how to do one。 (您必须注释掉 TypeScript 类型注释。)

标签: reactjs typescript usecallback


【解决方案1】:

您的两个useCallback 调用中都有一层额外的函数。与useMemo 不同,useCallback 直接接受它应该记忆的回调,而不是构建回调的函数。

所以:

const getOnClick = useCallback(
    (rec: GenericRec): (() => void) => {
//                                     ^−−−− no () => here
        console.log("getOnClick");
        setSelectedRecord(rec);
    },
    [],
);

const openRecord = useCallback(
    (row: Row<Record>) =>
//                       ^−−−− no () => here
        getOnClick({ id: row.original.id, name: row.original.name })
    ,
    [getOnClick],
);

实时示例(TypeScript 类型注释被注释掉):

const { useState, useCallback } = React;

function Example() {
    const [selectedRecord, setSelectedRecord] = useState(null);
    const getOnClick = useCallback(
        (rec/*: GenericRec*/)/*: (() => void)*/ => {
            console.log("getOnClick");
            setSelectedRecord(rec);
        },
        []/*,*/
    );

    const openRecord = useCallback(
        (row/*: Row<Record>*/) =>
    //                         ^−−−− no () => here
            getOnClick({ id: row.original.id, name: row.original.name })
        ,
        [getOnClick]/*,*/
    );

    const addRecord =() => {
        console.log("addRecord");
        openRecord({
            original: {
                id: 1,
                name: "The record"
            }
        });
    };

    return (
        <div>
            <input type="button" value="Click Me" onClick={addRecord} disabled={!!selectedRecord} />
            {selectedRecord && <span>Selected record: "{selectedRecord.name}" ({selectedRecord.id})</span>}
            {!selectedRecord && <em>No record selected</em>}
        </div>
    );
}

ReactDOM.render(<Example/>, document.getElementById("root"));
<div id="root"></div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.0/umd/react-dom.production.min.js"></script>

【讨论】:

  • 谢谢你的回复,但还是一样,getOnClick没有被调用
  • @KaoutarBELLA - 是的 - 请参阅 live example。如果调用openRecord,则调用getOnClick
  • true ,我的回调正在返回一个函数......谢谢@T.J
  • @KaoutarBELLA - 然后你必须调用openRecord 的结果。正如我在这个问题上所说,请用 minimal reproducible example 来更新您的问题,以展示问题,最好是使用 Stack Snippets([&lt;&gt;] 工具栏按钮)的 runnable 问题。 Stack Snippets 支持 React,包括 JSX; here's how to do one.
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-01
  • 2017-03-13
  • 1970-01-01
  • 1970-01-01
  • 2010-10-10
相关资源
最近更新 更多