Javascript 如何处理纯功能组件中的事件
根据,我们应该使用Redux,编写小型的、无状态的功能组件。下面是一个例子: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
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
passonItemClicked
函数作为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>
)