组件未重新加载但状态随 useState 发生变化
Component not reloading but state is changing with useState
我不是 React 的新手,但我是使用 hooks 的新手,今天我在玩 selected 元素和 selection/unselection 的数组。
如果它们是 selected 则显示一个图标,如果不是,则显示另一个图标(我只是更改名称 prop,而不是组件本身。
console.log 我做的每个渲染都显示了正确的结果,但它在 JSX 上没有按预期工作。
当我取消 select 时,渲染似乎只重新加载(显示正确的图标)。以列表形式解释程序和我的问题:
- 所有元素都selected
- 我取消select一个元素(从列表中删除),图标改变。
- 我select返回元素(添加到列表),图标不改变。
- 我unselect另一个元素,然后它就可以工作了,组件是
重新加载
这是我的对象数组:
const dies = [
{
id: 1,
nomDia : 'Dies',
dataDia : 'previs'
},
{
id: 2,
nomDia : 'Dies',
dataDia : 'previs'
},
{
id: 3,
nomDia : 'Dies',
dataDia : 'previs'
}
]
这是 useSate 声明:
const [diesSeleccionats, setDiesSeleccionats] = useState(dies)
这是检查是否 selected 的函数和 selected 列表中的 adds/removes 的函数:
// check if selected
const estaSeleccionat = (dia) => {
return diesSeleccionats.findIndex((aDia) => aDia.id === dia.id ) != -1
}
// remove selected or add selected
const gestionarSeleccionats = (dia) => {
if(estaSeleccionat(dia)){
return diesSeleccionats.filter((aDia) => aDia.id !== dia.id)
} else {
diesSeleccionats.push(dia)
return diesSeleccionats
}
}
组件如下:
dies.map((dia) => (
<View key={dia.id} style={{flexDirection: 'row', marginTop: 5, alignSelf: 'flex-end'}}>
<TouchableOpacity
style={{backgroundColor: Colors.llistat1 + 'CC'}}
key={dia.id}
onPress={() => setDiesSeleccionats(gestionarSeleccionats( dia ))}
>
<Text style={{fontSize: 18, color: Colors.titolsPantalles}}> {dia.nomDia} </Text>
</TouchableOpacity>
<TouchableOpacity
style={{
minWidth: 24,
backgroundColor: Colors.llistat1 + 'CC',
marginLeft: 5,
paddingHorizontal:5,
justifyContent:'center', alignItems: 'center'}}
onPress={ () => setDiesSeleccionats(gestionarSeleccionats( dia ))}
>
<Ionicons name={ estaSeleccionat( dia ) ? "md-checkmark" : "md-close"} size={18} color={Colors.titolsPantalles} />
</TouchableOpacity>
</View>
))
您可以看到 <Ionicons> 如果元素在 selected 列表中,则名称由定义。
我每次重新渲染的日志都显示了正确的结果。 (检查函数的布尔值,以及对象数组中的正确元素)
谢谢。
我认为这个问题与变异 diesSeleccionats
而不是复制有关。我认为您需要复制它以提供给 setDiesSeleccionats
,以便 React 可以分析差异并呈现正确的更新状态。
const gestionarSeleccionats = (dia) => {
const selections = [...diesSeleccionats];
if(estaSeleccionat(dia)){
return selections.filter((aDia) => aDia.id !== dia.id);
} else {
selections.push(dia)
return selections;
}
}
我不是 React 的新手,但我是使用 hooks 的新手,今天我在玩 selected 元素和 selection/unselection 的数组。
如果它们是 selected 则显示一个图标,如果不是,则显示另一个图标(我只是更改名称 prop,而不是组件本身。
console.log 我做的每个渲染都显示了正确的结果,但它在 JSX 上没有按预期工作。
当我取消 select 时,渲染似乎只重新加载(显示正确的图标)。以列表形式解释程序和我的问题:
- 所有元素都selected
- 我取消select一个元素(从列表中删除),图标改变。
- 我select返回元素(添加到列表),图标不改变。
- 我unselect另一个元素,然后它就可以工作了,组件是 重新加载
这是我的对象数组:
const dies = [
{
id: 1,
nomDia : 'Dies',
dataDia : 'previs'
},
{
id: 2,
nomDia : 'Dies',
dataDia : 'previs'
},
{
id: 3,
nomDia : 'Dies',
dataDia : 'previs'
}
]
这是 useSate 声明:
const [diesSeleccionats, setDiesSeleccionats] = useState(dies)
这是检查是否 selected 的函数和 selected 列表中的 adds/removes 的函数:
// check if selected
const estaSeleccionat = (dia) => {
return diesSeleccionats.findIndex((aDia) => aDia.id === dia.id ) != -1
}
// remove selected or add selected
const gestionarSeleccionats = (dia) => {
if(estaSeleccionat(dia)){
return diesSeleccionats.filter((aDia) => aDia.id !== dia.id)
} else {
diesSeleccionats.push(dia)
return diesSeleccionats
}
}
组件如下:
dies.map((dia) => (
<View key={dia.id} style={{flexDirection: 'row', marginTop: 5, alignSelf: 'flex-end'}}>
<TouchableOpacity
style={{backgroundColor: Colors.llistat1 + 'CC'}}
key={dia.id}
onPress={() => setDiesSeleccionats(gestionarSeleccionats( dia ))}
>
<Text style={{fontSize: 18, color: Colors.titolsPantalles}}> {dia.nomDia} </Text>
</TouchableOpacity>
<TouchableOpacity
style={{
minWidth: 24,
backgroundColor: Colors.llistat1 + 'CC',
marginLeft: 5,
paddingHorizontal:5,
justifyContent:'center', alignItems: 'center'}}
onPress={ () => setDiesSeleccionats(gestionarSeleccionats( dia ))}
>
<Ionicons name={ estaSeleccionat( dia ) ? "md-checkmark" : "md-close"} size={18} color={Colors.titolsPantalles} />
</TouchableOpacity>
</View>
))
您可以看到 <Ionicons> 如果元素在 selected 列表中,则名称由定义。
我每次重新渲染的日志都显示了正确的结果。 (检查函数的布尔值,以及对象数组中的正确元素)
谢谢。
我认为这个问题与变异 diesSeleccionats
而不是复制有关。我认为您需要复制它以提供给 setDiesSeleccionats
,以便 React 可以分析差异并呈现正确的更新状态。
const gestionarSeleccionats = (dia) => {
const selections = [...diesSeleccionats];
if(estaSeleccionat(dia)){
return selections.filter((aDia) => aDia.id !== dia.id);
} else {
selections.push(dia)
return selections;
}
}