Reactjs 功能组件随useMoom/React.memo一起消失
我正试着集中精力使用Reactjs 功能组件随useMoom/React.memo一起消失,reactjs,react-native,Reactjs,React Native,我正试着集中精力使用usemo(或React.memo)来优化一些组件渲染 我有个无法解释的问题 我有以下代码: [...] const [ cards, setCards ] = useState<Card[]>([]) function addCard(){ setCards([...cards, {name: 'card-' + cards.length, counter: 0, type: 'memo'}]) } func
usemo
(或React.memo
)来优化一些组件渲染
我有个无法解释的问题
我有以下代码:
[...]
const [ cards, setCards ] = useState<Card[]>([])
function addCard(){
setCards([...cards, {name: 'card-' + cards.length, counter: 0, type: 'memo'}])
}
function onPressCard(index: number){
cards[index].counter += 1
setCards([...cards])
}
return (
[...]
{
cards.map((x, index) =>
<Card key={index} {...x} onPress={() => onPressCard(index)}/>
}
[...]
)
[…]
const[cards,setCards]=useState([])
函数addCard(){
setCards([…cards,{name:'card-'+cards.length,计数器:0,键入:'memo'}])
}
印刷卡上的功能(索引:编号){
卡片[索引]。计数器+=1
设置卡片([…卡片])
}
返回(
[...]
{
卡片.地图((x,索引)=>
onPressCard(索引)}/>
}
[...]
)
和卡定义为
const Card: FC<CardProps> = function({ name, counter, onPress }){
const counterRef = useRef(0)
const item = useMemo(() => {
counterRef.current +=1
return (
<RectButton onPress={onPress} style={[styles.card, { backgroundColor: 'lightcoral' }]}>
<Text style={styles.text}>{ name }</Text>
<Text style={styles.counter}> { `counter ${counter}` }</Text>
<Text style={styles.counter}>{ `render: ${counterRef.current}`}</Text>
</RectButton>
)
}, [name, counter])
return item
}
const areEqual = function(prevProps: Card, nextProps: Card){
return (
(prevProps.name === nextProps.name) &&
(prevProps.counter === nextProps.counter)
)
}
const Card = React.memo<CardProps>(({ name, counter, onPress }) => {
const counterRef = useRef(0)
counterRef.current +=1
return (
<RectButton onPress={onPress} style={[styles.card, { backgroundColor: 'lightcoral' }]}>
<Text style={styles.text}>{ name }</Text>
<Text style={styles.counter}> { `counter ${counter}` }</Text>
<Text style={styles.counter}>{ `render: ${counterRef.current}`}</Text>
</RectButton>
)
}, areEqual)
常量卡:FC=函数({name,counter,onPress}){
const counterRef=useRef(0)
const item=useMoom(()=>{
反向参考电流+=1
返回(
{name}
{`counter${counter}`}
{`render:${counterRef.current}`}
)
},[姓名,柜台])
退货项目
}
为什么,当我按下列表中的一个项目(最后一个除外)时,以下所有项目都消失了?
编辑:同样的情况发生在定义为
const Card: FC<CardProps> = function({ name, counter, onPress }){
const counterRef = useRef(0)
const item = useMemo(() => {
counterRef.current +=1
return (
<RectButton onPress={onPress} style={[styles.card, { backgroundColor: 'lightcoral' }]}>
<Text style={styles.text}>{ name }</Text>
<Text style={styles.counter}> { `counter ${counter}` }</Text>
<Text style={styles.counter}>{ `render: ${counterRef.current}`}</Text>
</RectButton>
)
}, [name, counter])
return item
}
const areEqual = function(prevProps: Card, nextProps: Card){
return (
(prevProps.name === nextProps.name) &&
(prevProps.counter === nextProps.counter)
)
}
const Card = React.memo<CardProps>(({ name, counter, onPress }) => {
const counterRef = useRef(0)
counterRef.current +=1
return (
<RectButton onPress={onPress} style={[styles.card, { backgroundColor: 'lightcoral' }]}>
<Text style={styles.text}>{ name }</Text>
<Text style={styles.counter}> { `counter ${counter}` }</Text>
<Text style={styles.counter}>{ `render: ${counterRef.current}`}</Text>
</RectButton>
)
}, areEqual)
const areEqual=函数(前一个道具:卡,下一个道具:卡){
返回(
(prevProps.name==nextProps.name)&&
(prevProps.counter===nextProps.counter)
)
}
const Card=React.memo({name,counter,onPress})=>{
const counterRef=useRef(0)
反向参考电流+=1
返回(
{name}
{`counter${counter}`}
{`render:${counterRef.current}`}
)
},他们是平等的)
问题在于,已记忆的组件包含对旧版本的onPress
的引用。旧版本的onPress
在其关闭中有一个旧版本的cards
。点击按钮将调用旧函数,该函数根据旧状态更新父级状态,并且旧状态中的项目较少。
修复此问题的一个选项是使用setCards的函数版本,以便根据最新状态进行更新。此外,我更新了代码,不再对旧卡进行变异:
function onPressCard(index: number){
setCards(oldCards => {
const newCards = [...oldCards];
newCards[index] = {...oldCards[index]};
newCards[index].counter += 1;
return newCards;
})
}
另一个选项是将onPress添加到UseMoom的条件中,但由于onPress函数一直在更改,因此您最终无法从记忆中获得任何东西。如果onPress本身使用useCallback进行了记忆,则可以改进这一点:
const onPressCard = useCallback((index: number) => {
cards[index].counter += 1;
setCards([...cards]);
}, [cards])
// ...
const item = useMemo(() => {
counterRef.current +=1
return ( /* jsx omitted for brevity */ )
}, [name, counter, onPress])
onPressCard的作用是什么?我不确定useMemo是否被设计用于记忆整个组件。它与React.memo完全不同。@NicholasTower我更新了我的question@nubinub当我使用React.memo时,也会发生同样的情况,使用相同的comparisonPerfect,你能用
useCallback
演示一个例子吗ne@Orelus我在.UseCallback中添加了这一点,它与useMemo非常相似。它只是假设您想要记忆一个函数。UseCallback(()=>“hello world”)
与useMemo(()=>()=>()=>“hello world”)相同。
;