Home > Enterprise >  multiple switches in react native how to
multiple switches in react native how to

Time:09-28

I'm trying to make multiple switches, the problem is that when I enable / disable 1, all others enable / disable together.

useEffect is being used for me to bring my data from my API.

const [data, setData] = useState([]);


  useEffect(() => {
    async function fetchData() {
      await api
        .get('/synchronization/group/true')
        .then(response => setData(response.data.data))
        .catch(error => setData(error));
    }

    fetchData();
  }, []);

  useEffect(() => {
    // Just return data
  }, [data]);


const [isEnabled, setIsEnabled] = useState({
  enabled: false
});

const toggleSwitch = () => setIsEnabled((toggle) => !toggle);

const Item = ({ id, title }) => {

  return (
    <View>
      <TextList>{title}</TextList>

      <Switch
        key={id}
        onValueChange={toggleSwitch}
        value={isEnabled}
      />
    </View>
  );
};

And here my render switches with looping, It adds component according to the records in the database

const renderItem = ({ item }) => {
  const date = new Date(item.synchronization)

  const formattedDate = date.toISOString().split('T')[0];

  return <Item id={item.id} title={'Sincronização: '   formattedDate.split('-').reverse().join('/')} />
};

return (
  <Container>
    <List
      data={data}
      renderItem={renderItem}
      keyExtractor={item => item.id.toString()}
    />
    <TouchableButton onPress={() => { navigation.navigate('Loading') }}>
      <TextButton>Carregar para offline</TextButton>
    </TouchableButton>
  </Container>
);
}

My screen:

Example

CodePudding user response:

If I understand correctly, all the code that you provided is in one component. You need to store the state of switch button separately.

Try it:

const Item = ({id, title, value, onValueChange}) => (
    <View>
        <TextList>{title}</TextList>

        <Switch
            onValueChange={onValueChange}
            value={value}
        />
    </View>
);

const Component = ({navigation}) => {
    const [data, setData] = useState([]);

    useEffect(() => {
        const fetchData = async () => {
            await api
                .get('/synchronization/group/true')
                .then(response => setData(response.data.data))
                .catch(error => setData(error));
        }

        fetchData();
    }, []);

    useEffect(() => {
        // Just return data
    }, [data]);

    const [state, setState] = useState({
        switches: {}
    });

    const toggleSwitch = useCallback((id) => () => setState((state) => ({
        ...state,
        switches: {
            ...state.switches,
            [id]: !state.switches[id]
        }   
    })), []);

    const renderItem = useCallback(({item}) => {
        const date = new Date(item.synchronization)

        const formattedDate = date.toISOString().split('T')[0];

        return <Item id={item.id} title={'Sincronização: '   formattedDate.split('-').reverse().join('/')} value={!!state.switches[item.id]} onValueChange={toggleSwitch(item.id)}/>
    }, [state.switches, toggleSwitch]);

    return (
        <Container>
            <List
                data={data}
                renderItem={renderItem}
                keyExtractor={item => item.id.toString()}
            />
            <TouchableButton onPress={() => navigation.navigate('Loading')}>
                <TextButton>Carregar para offline</TextButton>
            </TouchableButton>
        </Container>
    );
};

CodePudding user response:

If you don't need to store states of all switches in your parent component, you can declare state in a component that will be rendered in list.

Here you declare state, that will be handled locally in this component.

const SwitchComponent = (item => {
  const [switchState, setSwitchState] = useState(item.state)
  return (
    <Switch value={switchState} onValueChange={ () => setSwitchState(prevState => !prevState)}/>
  )
})

then it can be rendered in List

<View style={styles.container}>
  {arr.map(item => (<SwitchComponent item={item}/>))}
</View>

Rendering as many switches as you want, with state handled separately.
You can try it here.

  • Related