Issue
Hello everyone here I am again. I want to create an specific event foreach component created from the result of the JSON response.
I've created each component using .map, it works I can create the Collapse headers from the result. If the result from JSON are 3 it creates 3 different headers, but my problem is with the component inside, every time I press the TouchableWithoutFeedBack it renders all the Collapse Body based on the last Collapse Header click, but I need to render only the Collapse Body related with clicked Header.
I have a functional component which have a Request to retrieve the categories and fill the Collapse Header, then on the click of the Header I need to fill a custom component based on the Header Category.
How can I solve this? If someone could help me, I would really appreciate it.
{auditCategory.map(r =>(
<Collapse>
<CollapseHeader key={r.id} >
<TouchableWithoutFeedback onPress={()=> {
// console.log("TESTE:"+r.id)
axios.get("http://10.113.16.113:8081/api/audititem/findbycategorycheckl?checklistid="+checklistid+"&categoryid="+r.id,{
}).then
(function (response){
setAuditItems(response.data);
// console.log(response.data);
}).catch(error => {
console.log(error);
})
}}>
<View style={styles.collapHead}>
<Text style={styles.collapHeadInput} >{r.categorY_DESCRIPTION} </Text>
</View>
</TouchableWithoutFeedback>
</CollapseHeader>
<CollapseBody>
<ScrollView horizontal={true}>
{auditItems.map(r =>(
<AuditItem key={r.id} title={r.subcategorY_DESCRIPTION} od={r.od}></AuditItem>
))}
</ScrollView>
</CollapseBody>
</Collapse>
))}
This is the response from axios.get :
[
{
"id": 3,
"subcategorY_DESCRIPTION": " Test 1 SubCategory",
"checklisT_ID": 1,
"auditcategorY_ID": 2,
"od": 300,
"creatioN_DATETIME": "2020-03-06T00:00:00",
"status": true,
"locatioN_ID": 1,
"shoW_SCANCODE": true,
"shoW_CAPTUREPHOTO": true,
"shoW_COMMENTS": true
},
{
"id": 9,
"subcategorY_DESCRIPTION": "Test 2",
"checklisT_ID": 1,
"auditcategorY_ID": 2,
"od": 10,
"creatioN_DATETIME": "2020-04-06T00:00:00",
"status": true,
"locatioN_ID": 1,
"shoW_SCANCODE": true,
"shoW_CAPTUREPHOTO": true,
"shoW_COMMENTS": true
}
]
Solution
You seem to be using some sort of state object. I am assuming you are using the useState
hook with something like const [auditItems, setAuditItems] = useState('')
.
I am suggesting you use an empty object to start. So:
const [auditItems, setAuditItems] = useState({})
Then when you retrieve the values you wish to set to auditItems
, you can set it as a property of the object that already exists. Like so: setAuditItems({...auditItems, [r.id]: response.data})
Then you can check if the key exists when you render the items:
{auditItems[r.id] && auditItems[r.id].map(r =>(
<AuditItem key={r.id} title={r.subcategorY_DESCRIPTION} od={r.od}></AuditItem>
))}
If you don't care to save the previous values on the next click, you can simply make another state hook that tracks the id currently clicked and use that to conditionally display the auditItems
map. Or just remove the ...auditItems
from setAuditItems
.
Any of that make sense?
Answered By - Abraham Labkovsky
Answer Checked By - - Jay B. (ReactFix Admin)