aff_cue
aff_cue

Reputation: 73

How to Update state in return()?

I want to change the state when I get id of 5/6 or 7, after TouchableOpacity. Because I want to show the "Other Things" button one time whether id is 5/6 or 7.

export function HomePage({ navigation }) {

   const [parentServiceCheck, setParentServiceCheck] = useState({ check: '0' });

   return (
       <View>
           <FlatList numColumns={2} contentContainerStyle={{ margin: 7, flex: 1 }} keyExtractor={(item, index) => item.id} data={allService} renderItem={itemData => (
               <View style={{ flexDirection: 'column', flex: 1 }}>
                   {
                       (itemData.item.id == 5 || itemData.item.id == 6 || itemData.item.id == 7) && parentServiceCheck.check == '0' ?
                           <TouchableOpacity onPress={() => pressHandler(itemData.item.id)} style={{ margin: 7 }}>
                               <Card titlebtn="Other Things" src={itemData.item.service_image} sty={{ height: 180, }} />
                           </TouchableOpacity>
                           // Now here I want to setParentServiceChildCheck({check: '1'}) when itemData.item.id has 5/6/7
                           :
                           <TouchableOpacity onPress={() => pressHandler(itemData.item.id)} style={{ margin: 7 }}>
                               <Card titlebtn={itemData.item.service_name} src={itemData.item.service_image} sty={{ height: 180, }} />
                           </TouchableOpacity>
                   }
               </View>
           )}
           />
       </View>
   )
}

Upvotes: 0

Views: 44

Answers (2)

Milind Agrawal
Milind Agrawal

Reputation: 2944

You can't really update or execute any JS code like that. I would suggest to go through few training to learn about how things work in React JSX.

For now, if you want to update the state then you should be good to use it in useEffect as shown below

export default function HomePage({ navigation }) {
  const [parentServiceCheck, setParentServiceCheck] = useState({ check: '0' });

  useEffect(() => {
    const hasValidId = allService.find(_hasValidId);

    // This will get called only once after first render
    // This will execute only when id's are 5, 6 or 7 which is your requirement 
    if (hasValidId) {
      setParentServiceChildCheck({ check: '1' });
    }
  }, []);

  const _hasValidId = itemData => {
    const itemId = itemData?.item?.id;
    const validItemIds = [5, 6, 7];
    return validItemIds.includes(itemId);
  };

  const _renderItem = itemData => {
    const itemId = itemData?.item?.id;
    let content = null;

    if (_hasValidId(itemData)) {
      if (parentServiceCheck.check === '0') {
        content = (
          <TouchableOpacity onPress={() => pressHandler(itemId)} style={{ margin: 7 }}>
            <Card titlebtn="Other Things" src={itemData.item.service_image} sty={{ height: 180 }} />
          </TouchableOpacity>
        );
      } else {
        content = (
          <TouchableOpacity onPress={() => pressHandler(itemId)} style={{ margin: 7 }}>
            <Card
              titlebtn={itemData.item.service_name}
              src={itemData.item.service_image}
              sty={{ height: 180 }}
            />
          </TouchableOpacity>
        );
      }
    }

    return <View style={{ flexDirection: 'column', flex: 1 }}>{content}</View>;
  };

  return (
    <View>
      <FlatList
        numColumns={2}
        contentContainerStyle={{ margin: 7, flex: 1 }}
        keyExtractor={(item, index) => item.id}
        data={allService}
        renderItem={_renderItem}
      />
    </View>
  );
}

FYI, you might need to change few lines as the whole component code is not shared and I don't know about your business logic.

Upvotes: 1

Igor Lipin
Igor Lipin

Reputation: 41

You should never update state in return / render function. It will make infinite rendering loop.

Upvotes: 1

Related Questions