Вывод иконок по условию
Была попытка вывести статус по условию в виде иконки через изменение состояния при рендеринге, однако столкнулась со следующей проблемой: в консоль значение статуса выводит корректно при сравнении из полученных данных из бд, но в состояние записывает всегда независимо от значения статуса (переменных 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 шт):
Функции 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" />}