изменить значок после нажатия на него - PullRequest
1 голос
/ 04 августа 2020

У меня есть компонент, который выглядит следующим образом:

const criteriaList = [
  'Nur Frauen',
  'Freunde Zweiten Grades',
];

export const FilterCriteriaList: React.FunctionComponent = () => {
  const [state, setState] = useState(false);

  useEffect(() => {
    console.log('state is,', state);
  });

  const myFunction = () => {
    console.log('checking state', state);
    if (state == false) {
      setState(true);
    } else {
      setState(false);
    }
  };

  return (
    <View style={styles.container}>
      <View style={styles.horizontalLine} />
      {criteriaList.map((item: string, index: number) => (
        <View key={index}>
          <View style={styles.criteriaRow}>
            <TouchableOpacity 
              onPress={() => {
                myFunction();
              }}>
              <Icon
                name="circle-thin"
                color="#31C283"
                size={moderateScale(20)}
              />
            </TouchableOpacity>
            <Text style={styles.text}>{item}</Text>
          </View>
          
          <View style={styles.horizontalLine} />
        </View>
      ))}
    </View>
  );
};

В настоящее время я использую значок в виде тонкого круга. Я хочу изменить его так, чтобы каждый раз, когда я нажимаю на значок, он превращается в значок точка-круг-o. Как радиокнопки. Однако я не совсем уверен, как это сделать.

Я думал об использовании тернарных операторов, но, поскольку я сопоставляю свои поля Idk, как совокупно setStates. Может, с помощью индекса? Я не хочу делать отдельное состояние для каждого поля. Вот аналогичная демонстрация закуски:

https://snack.expo.io/toTSYc2fD

Я хочу иметь возможность выбирать несколько вариантов / отменять выбор. Я не хочу применять одно и то же правило ко всем полям вместе.

Примечание: функцию onPress также можно использовать непосредственно на значке вместо TouchableOpacity (хотя это не рекомендуется)

Ответы [ 2 ]

2 голосов
/ 04 августа 2020

Использование троичности кажется мне правильным подходом. Разве вы не можете сделать что-то вроде:

name={state ? 'dot-circle-o' : 'circle-thin'}

Вы также можете реорганизовать свою функцию:

 const myFunction = () => {
    console.log('checking state', state);
    setState(!state)
 };

Если у вас несколько полей, есть много способов справиться с этим. Вы можете вызвать useState несколько раз, например:

const [field1, setField1] = useState(false);
const [field2, setField2] = useState(false);

Вы также можете сохранить все поля в одном и том же состоянии:

const [state, setState] = useState({field1: false, field2: false});

...

  const myFunction = (fieldName) => {
    console.log('checking state', state);
    setState({...state, [fieldName]: !state[fieldName]})
  };

Я думаю, вы тогда использовали бы item как «fieldName?» В этом случае:

return (
    <View style={styles.container}>
      <View style={styles.horizontalLine} />
      {criteriaList.map((item: string, index: number) => (
        <View key={index}>
          <View style={styles.criteriaRow}>
            <TouchableOpacity 
              onPress={() => {
                myFunction(item);
              }}>
              <Icon
                name={state[item] ? 'dot-circle-o' : 'circle-thin'}
                color="#31C283"
                size={moderateScale(20)}
              />
            </TouchableOpacity>
            <Text style={styles.text}>{item}</Text>
          </View>
          
          <View style={styles.horizontalLine} />
        </View>
      ))}
    </View>
  );

И для создания начального состояния:

const initialState = {}
criteriaList.forEach(item => initialState[item] = false)
const [state, setState] = useState(initialState);

1 голос
/ 04 августа 2020

Код будет примерно таким, как показано ниже. Вы должны установить индекс выбранного элемента в качестве состояния и использовать его для выбора значка.

const criteriaList = [
  {title:'My List',checked:false},
  {title:'Friends listt',checked:false},
  {title:'Not Good',checked:false},
  {title:'Sweet and sour',checked:false},
  {title:'Automatic',checked:false},
];

export const FilterCriteriaList: React.FunctionComponent = () => {
  const [state, setState] = useState(criteriaList);

  useEffect(() => {
    console.log('state is,', state);
  });

  const myFunction = (index) => {
    console.log('checking state', state);
    const arr=[...state];
    
    arr[index].checked=arr[index].checked?false:true;
    setState(arr);
    
  };

  return (
    <View style={styles.container}>
      <View style={styles.horizontalLine} />
      {criteriaList.map((item: Any,index:number) => (
        <View key={item}>
          <View key={item} style={styles.criteriaRow}>

              <Icon 
                style={styles.icon}
                name={item.checked?"circle":"circle-thin"}
                color="#31C283"
                size={moderateScale(20)}
                onPress= {()=>myFunction(index)}
              />
            <Text style={styles.text}>{item.title}</Text>
          </View>
          
          <View style={styles.horizontalLine} />
        </View>
      ))}
    </View>
  );
};
...