I am using ListItem from React Native Elements and have added a cheakbox:
{items.map((l, i) => (
<ListItem.Swipeable
key={i}
<ListItem.CheckBox
iconType='material'
checkedIcon='clear'
uncheckedIcon='add'
checkedColor='red'
checked={false}
//onPress={something} Need to write (call here) function here that will change checked state and do other stuff
/>
<ListItem.Content>
<ListItem.Title>
{l.time}
</ListItem.Title>
</ListItem.Content>
<ListItem.Chevron />
</ListItem.Swipeable>
))}
I need to be able to press on the ListItem.CheckBox and change the checked state as well as get the value of the mapped l
object.
I know how to pass an l
object from mapped array on the press to some function but don't know how to return value to checked={false}
, and if it's possible do more stuff with this element.
I have read a lot about refs and almost all are about class-based components and about manually creating refs for specific elements. The issue here is that this is an array of elements mapped into listview so this needs to be done on the flay.
Keep in mind that examples from the documentation on the checkbox don't work in functional components. Example: checked={this.state.checked}
The point of this is to be able to select multiple items from the list and do some actions on objects that are tie to them.
Any pointers are appreciated.
react-native: 0.63.2
CodePudding user response:
You can manage all state from the parent component while giving each child component a referance to setState
(or a function that use setState
inside). You can send checked
of each object in the list to each corresponding child component as a prop. This way, as the state is kept in the parent component, each state change reflects on the UI.
Sample component:
import { useState } from 'react'
const DEFAULT_ITEMS = [
{ id: "id_akdjk", label: "quora", checked: false },
{ id: "id_xlhwi", label: "library", checked: false },
{ id: "id_xoqix", label: "reddit", checked: true }
]
const ListItem = ({ label, checked, change }) => {
return(
<div>
<input type="checkbox" onChange={change} checked={checked}/>
<label htmlFor="vehicle1">{label}</label><br/>
</div>
)
}
export default function Component() {
const [items, setItems] = useState(DEFAULT_ITEMS)
const handleInputChange = (index) => {
// manipulate copy of state. (not state itself)
const copyState = [...items]
// updating that specific indice
copyState.splice(index,
1,
{...items[index], checked: !items[index]["checked"]})
setItems(copyState)
}
return (
<div>
{ items.map((el, i) => {
return <ListItem
key={i}
label={el.label}
checked={el.checked}
change={() => handleInputChange(i)}/>
})}
<div>
<p>You chose:</p> { items.map((el) => el.checked ? el.label : '').join(' ') }
</div>
</div>
)
}
So your onPress
would be:
// assuming you are using this data as the state
const DEFAULT_ITEMS = [
{ id: "id_akdjk", checked: false },
{ id: "id_xlhwi", checked: false },
{ id: "id_xoqix", checked: false }
]
...
const [items, setItems] = useState(DEFAULT_ITEMS)
const handleInputChange = (index) => {
// manipulate copy of state. (not state itself)
const copyState = [...items]
// updating that specific indice
copyState.splice(index,
1,
{...items[index], checked: !items[index]["checked"]})
setItems(copyState)
}
//...
onPress={() => handleInputChange(i)}
P.S. using index to update state is not a good idea. Having an id
for each object is a better practise