Javascript 如何处理纯功能组件中的事件

Javascript 如何处理纯功能组件中的事件,javascript,reactjs,redux,jsx,Javascript,Reactjs,Redux,Jsx,根据,我们应该使用Redux,编写小型的、无状态的功能组件。下面是一个例子: const ListView = ({items}) => ( <ul> {items.map(item => <ItemView item={item}/>)} </ul> ) const ItemView = ({item}) => ( <li><a>{item.name}</a>&l

根据,我们应该使用Redux,编写小型的、无状态的功能组件。下面是一个例子:

const ListView = ({items}) => (
    <ul>
        {items.map(item => <ItemView item={item}/>)}
    </ul>
)

const ItemView = ({item}) => (
    <li><a>{item.name}</a></li>
)
const ListView=({items})=>(
    {items.map(item=>)}
) const ItemView=({item})=>(
  • ,这是将导致性能损失的反模式

    显然,可以在
    ItemView
    组件内处理事件,并注入
    item
    。但是,如果要避免在渲染函数内创建函数,则需要将其设置为类组件

    这是一种非常常见的模式,我想找到一种简单的方法来处理这个问题,使用功能组件,而不会导致性能问题。你有什么建议


    如果没有办法做到这一点,我将根本无法使用功能组件。因为我经常想,在某个时候,我需要将每个功能组件转换为一个类。

    在做了更多思考后,我认为我找到了方法。我意识到我们需要更多的Redux容器。不仅仅是对main来说p级组件,但也适用于可重用的子组件

    上面的例子可以这样解决:

    const ListView = ({items, onItemClicked}) => (
        <ul>
            {items.map(item => <ItemContainer item={item} onItemClicked={onItemClicked}/>)}
        </ul>
    )
    
    const ItemView = ({item, onClick}) => (
        <li><a onClick={onClick}>{item.name}</a></li>
    )
    
    const mapDispatch = (dispatch, {item, onItemClicked}) => ({
        onClick: (event) => {
            event.preventDefault()
            onItemClicked(item)
        }
    })
    
    const ItemContainer = connect(null, mapDispatch)(ItemView)
    
    const ListView=({items,onItemClicked})=>(
    
      {items.map(item=>)}
    ) const ItemView=({item,onClick})=>(
  • {item.name}
  • ) 常量mapDispatch=(dispatch,{item,onItemClicked})=>({ onClick:(事件)=>{ event.preventDefault() 已单击(项目) } }) const ItemContainer=connect(null,mapDispatch)(ItemView)

    在许多情况下,我们不需要将回调从外部组件传递到内部组件,因为我们可以直接从
    ItemContainer

    pass
    onItemClicked
    函数作为
    ItemView
    的道具,并将其用作
    onClick
    函数e> onitemclick
  • 让它接收一个事件,并从事件中获取

    <ItemView item={item} onItemClicked={onItemClicked}/>
    
    const ItemView = ({item, onItemClicked}) => (
        <li><a item={item} onClick={onItemClicked}>{item.name}</a></li>
    )
    
    
    const ItemView=({item,onItemClicked})=>(
    
  • {item.name}
  • )
    您可以将
    \u onClick
    移到函数之外-这样,它仍然在作用域内,但不会在每次组件呈现时重新初始化。也就是说,在这一点上,将其转换为类可能会更干净。不,您没有抓住要点。首先,您不能这样做,因为它引用了
    oNitemclick
    prop。当然您可以传递它。但问题是它每次都会创建一个新的绑定函数。请注意,
    \u onClick
    是一个返回函数的函数(我想它被称为高阶函数)。由于
    ItemView
    每次都会获得一个新的prop,这将打破“纯渲染”优化。问题是,是否有办法在不使用类的情况下实现这一点。抱歉,我不应该在早上喝咖啡之前发表评论!在这种情况下,我不确定解决方案。这不是有同样的问题吗?每次调用mapDispatch时,都会向onClick属性传递一个新函数。
    mapDispatch
    每当组件接收到新道具时调用(
    item
    ,在本例中,假设
    onItemClicked
    没有更改)。在这种情况下,我们希望组件重新呈现,因为它代表一个新项。在原始示例中,每次更改任何单个项时,都会重新呈现所有
    ItemView
    。好的,谢谢您的建议,但它实际上没有回答如何从event.const item=event.target.itemthit中移除该项的问题如果不起作用,则会出现以下错误:标记上的未知属性
    item
    。请从元素中删除此属性。但是,可以将引用作为数据属性存储在DOM中,例如
    data item={item.id}
    。事实上,这就是我们一直在做的。它只支持字符串,因此您只能存储ID之类的内容,或者将数据序列化为JSON。我不太喜欢这种解决方案。
    <ItemView item={item} onItemClicked={onItemClicked}/>
    
    const ItemView = ({item, onItemClicked}) => (
        <li><a item={item} onClick={onItemClicked}>{item.name}</a></li>
    )