Вывод иконок по условию

Была попытка вывести статус по условию в виде иконки через изменение состояния при рендеринге, однако столкнулась со следующей проблемой: в консоль значение статуса выводит корректно при сравнении из полученных данных из бд, но в состояние записывает всегда независимо от значения статуса (переменных statBlue, statEmpty) значения true для iconBlue и false для iconEmpty. Таким образом отображает на экранную форму не правильную иконку, только иконку соответствующую iconBlue.

Также возникает предупреждение с дискуссией по теме:

Warning: Cannot update a component from inside the function body of a different component. https://github.com/facebook/react/issues/18178

Возможно есть способ иначе проводить проверку на статус и выводить иконку?

import React, { useState, useEffect } from 'react';
import { Text, View, FlatList, SafeAreaView } from 'react-native';
 
type Note = {
  commentId: number; 
  systemName: string;
  commentStatus: string;
};

const DirectionLayout = () => {
 
  const [iconBlue, setIconBlue]= useState<boolean>(false);//Устранено без просрочки
  const [iconEmpty, setIconEmpty]= useState<boolean>(false);//Не устранено без просрочки
  
  const [isLoading, setLoading] = useState(true);
  const [data, setData] = useState<Note[]>([]);

  const getNotes = async () => {
    try {
      const response = await fetch('https://...');
      const json = await response.json();
      setData(json);
    } catch (error) {
      console.error(error);
    } finally {
      setLoading(false);
    }
  };

  useEffect(() => {
    getNotes();
  }, []);


  const iconFunction = (status: string) => {
 
    console.log((status == 'Устранено'));
    const statBlue = (status === 'Устранено');
    const statEmpty = (status === 'Не устранено');
    console.log(statBlue);
    console.log(statEmpty);

    //if ((status == 'Не устранено')==false){setIconBlue(true);}
    //if ((status == 'Не устранено')==true){setIconEmpty(true);}
    setIconBlue(statBlue);
    setIconEmpty(statEmpty);

    console.log(iconBlue);
    console.log(iconEmpty);
  };


  return (
    <SafeAreaView style={{ flex: 1, backgroundColor: 'white' }}>

      <View style={{
        flex: 1, alignItems: 'center'
      }}>
               { isLoading ? (
              <ActivityIndicator />
            ) : (
              <FlatList
                style={{width: '100%'}}
                data={data}
                keyExtractor={({commentId}) => commentId}
                renderItem={({item}) => (
                  
                  <View style={{ backgroundColor: '#E0F2FE', width: '100%', height: 32, justifyContent: 'center', marginBottom: 41, borderRadius: 8}}>
                      <Text style={{ fontSize: 16, color: '#334155', textAlign: 'left' }}>{item.systemName}</Text>    
                  <View style={{width: '7%', marginStart: 2, justifyContent: 'center'}}>

                     {iconFunction(item.commentStatus)}

                       {iconBlue ? ( <Ionicons name="checkmark-circle" size={25} color="#0072C8" />): (<View/>) } 
                       {iconEmpty ? ( <Ionicons name="checkmark-circle" size={25} color="#F0F9FF" />):(<View/>)}
                      
                      </View>
                  </View>
          )}
              />
            )}
      </View >
    </SafeAreaView >

  );
};


export default DirectionLayout;

При попытке выводить иконку следующим способом:

{(item.commentStatus ='Устранено') ? ( <Ionicons name="checkmark-circle" size={25} color="#0072C8" />): ''}

столкнулась с такой проблемой:

(NOBRIDGE) ERROR Warning: Error: Objects are not valid as a React child (found: object with keys {if}). If you meant to render a collection of children, use an array instead.


Ответы (1 шт):

Автор решения: Lagutkin Denis

Функции iconFunction меняет состояние родительского компонента и вызывается внутри рендера дочернего компонента. Это первая ошибка на которую вы указали. Это нужно убрать. Также setIconBlue и setIconEmpty не нужны в компоненте. Чтобы вывести компонент в зависимости от статуса попробуйте ваш второй вариант, обратите внимание на условную часть тернарного оператора, у вас там присвоение, не проверка. Также проверьте Ionicons, является ли компонентом.

Этот код:

{iconFunction(item.commentStatus)}

{iconBlue ? ( <Ionicons name="checkmark-circle" size={25} color="#0072C8" />): (<View/>) } 
{iconEmpty ? ( <Ionicons name="checkmark-circle" size={25} color="#F0F9FF" />):(<View/>)}
                  

заменить на

{item.commentStatus === 'Устранено' ? ( <Ionicons name="checkmark-circle" size={25} color="#0072C8" />): ''}

или чуть сокращенная форма

{item.commentStatus === 'Устранено' && <Ionicons name="checkmark-circle" size={25} color="#0072C8" />}
→ Ссылка