在REACT中进行开发时,我多次遇到了将项目传递给函数的需求,例如这样做:
// Inside a Hook component
return (
...
{nodes.map(n => <Node data={node} onClick={(e) => handleNodeClick(e, node)} />)}
);
基本上,我有一个变量nodes
,它可以来自props
,useMemo
等。然后,我为每个节点创建一个<Node>
组件。
最后,如您所见,<Node>
组件具有一个onClick
道具,它们触发一个函数。在THAT函数中,我需要具有所有数据的节点(想象一棵树的节点,具有唯一ID,图标等)。
所以,像在示例中那样编写,我实现了我所需要的,但是!我在return语句中有一个箭头函数,并且我还读到在render()
方法中有一个箭头函数是不好的。而且我想里面的return
语句也是如此一个Hook组件。
因此,为了克服箭头功能的使用,我多次使用attribute来避免这种情况。基本上是这样的:
// Inside a Hook component
const handleNodeClick = (e) => {
if (e.target instanceof HTMLElement) {
const nodeDOM = e.target.closest('[data-is-node]');
if (nodeDOM) {
const nodeIndex = e.target.getAttribute("data-node-index");
const node = nodes[nodeIndex];
...
}
}
}
return (
...
{nodes.map((n, i) => <Node
data={node}
data-is-node={''}
data-node-index={i}
onClick={handleNodeClick2} />)}
);
因此,正如您所看到的,最终在handleNodeClick2
中,我确实有需要的node
。但是,我想知道我是否需要做的所有事情都是值得的,还是应该只使用箭头功能。
希望我已经很好地解释了这个问题。特别是,我什至不确定短语“ render()
方法内的无箭头功能” 是否也适用于Hook组件。
答案 0 :(得分:1)
如果您想简化箭头函数而又没有尝试过的复杂性,则可以 创建一个更高阶的函数,该函数将要传递给回调的fun doAThing() {
val file = File("...")
file.writer().use{
for (x in 1..4) {
val response = async { makeHttpRequest(/*...*/) }
it.write(transform(response)) // This is, obviously, the blocking call.
}
}
}
并返回一个回调函数。
node
匿名内部箭头函数通常可以很好地在render函数中使用。有时不鼓励这样做的原因是,您实际上是将相同回调 implementation 传递给要映射的一堆元素,每个映射的元素都获得了函数的完整副本。创建和实例化所有这些回调函数可能并不昂贵,但是会产生一定的成本。在这种情况下,模式是简单地(一次)定义一个命名箭头函数回调并将引用传递给它。
// Higher Order Function to enclose `node` in function scope to be used later
// Function takes a node parameter and returns an event handler function
const handleNodeClick = node => e => {
// node in function scope
// do what you need
...
}
return (
...
{nodes.map((node, i) => (
<Node
data={node}
data-is-node={""}
data-node-index={i}
onClick={handleNodeClick2(node)}
/>
))}
);
与
items.map(item => <button onClick={e => { /* expensive callback code */}}>{item}</button>)
如果您担心的话,可以将其更进一步,并且也将地图的回调因素排除在外
const expensiveCallback = e => { /* expensive callback code */};
...
items.map(item => <button onClick={expensiveCallback}>{item}</button>)