I've a weird behavior here.
I'm trying to update a parent component from a child.
I've thus something like this for the child:
const LabelList = ({editable, boardLabels, cardLabels, size='normal', udpateCardLabelsHandler}) => {
return (
<DropDownPicker
labelStyle={{
fontWeight: "bold"
}}
badgeColors={badgeColors}
showBadgeDot={false}
items={items}
multiple={true}
open={open}
onChangeValue={(value) => udpateCardLabelsHandler(value)}
value={value}
setOpen={setOpen}
setValue={setValue} />
)
}
And, for the parent, something like this:
const CardDetails = () => {
const [updatedCardLabels, setUpdatedCardLabels] = useState([])
const [card, setCard] = useState({})
const [editMode, setEditMode] = useState(false)
// Handler to let the LabelList child update the card's labels
const udpateCardLabelsHandler = (values) => {
const boardLabels = boards.value[route.params.boardId].labels
const labels = boardLabels.filter(label => {
return values.indexOf(label.id) !== -1
})
console.log('updated labels',labels)
setUpdatedCardLabels(labels)
}
return (
<View style={{zIndex: 10000}}>
<Text h1 h1Style={theme.title}>
{i18n.t('labels')}
</Text>
<LabelList
editable = {editMode}
boardLabels = {boards.value[route.params.boardId].labels}
cardLabels = {card.labels}
udpateCardLabelsHandler = {udpateCardLabelsHandler} />
</View>
)
And, this just doesn't work: As soon as I try changing something in the DropDownPicker the application hangs. The console.log
statement isn't even executed and no errors show up in my expo console.
What's strange is that if I change the updateCardLabels
state to be a boolean for example, everything works ok (eg: the console.log
statement is executed):
const [updatedCardLabels, setUpdatedCardLabels] = useState(false)
// Handler to let the LabelList child update the card's labels
const udpateCardLabelsHandler = (values) => {
const boardLabels = boards.value[route.params.boardId].labels
const labels = boardLabels.filter(label => {
return values.indexOf(label.id) !== -1
})
console.log('updated labels',labels)
setUpdatedCardLabels(true)
}
Please note that updatedCardLabels
isn't used anywhere: it's a dummy variable that I'm just using to debug this issue (to make sure I was not ending in some endless render loop or something similar).
For the sake of completeness, here's what labels
looks like at line console.log('updated labels',labels)
(please not that I can only see this value when doing setUpdatedCardLabels(true)
as otherwise, when the code does setUpdatedCardLabels(labels)
, the console.log statement is not executed, as mentioned earlier):
updated labels Array [
Object {
"ETag": "a95b2566521a73c5edfb7b8f215948bf",
"boardId": 1,
"cardId": null,
"color": "CC317C",
"id": 9,
"lastModified": 1621108392,
"title": "test-label",
},
]
Does anybody have an explanation for this strange behavior?
Best regards,
Cyrille
So, I've found the problem: It was a side effect of the DrowpDownPicker.
I've solved it by changing my child as follow:
const LabelList = ({editable, boardLabels, cardLabels, size='normal', udpateCardLabelsHandler}) => {
const [open, setOpen] = useState(false);
const [value, setValue] = useState(cardLabels.map(item => item.id));
const theme = useSelector(state => state.theme)
// Updates parent when value changes
useEffect(() => {
if (typeof udpateCardLabelsHandler !== 'undefined') {
udpateCardLabelsHandler(value)
}
}, [value])
return (
<DropDownPicker
labelStyle={{
fontWeight: "bold"
}}
badgeColors={badgeColors}
showBadgeDot={false}
items={items}
multiple={true}
open={open}
value={value}
setOpen={setOpen}
setValue={setValue} />
)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.