0

Say, I have this toggle:

<IonToggle id="IonToggleDarkMode" slot="end" checked={vars.darkMode} onChange={darkModeToggle}></IonToggle>

vars.darkMode is the saved value of the toggle, so the state is set when loading the page. So, know I want to write a function that gets called onChange and I can't figure out how to pass or access the "checked" attribute here...

Let's do this for example:

function darkModeToggle() {
  togglestate = // ???
  console.log( togglestate )
}

How do I do that?

I also read something about onChange={e => darkModeToggle(e)} but to be honest, I don't get it ... e doesn't seem to transport the checked-attribute anywhere. I thought about running a selector for the toggles id and then reading its value but the API reference clearly states that 'value' is not to be used but 'checked' is.

Code for context:

import React from 'react';
//other import statements

const { useState } = React;
const DarkModeSwitch = () => {
  // here you set the initial state using the useState hook:
  const [isChecked, setIsChecked] = useState(false);
  const darkModeToggle = () => {
    console.log(isChecked);
    setIsChecked(!isChecked);
  }
}
//other logic, calculations, JS functions, etc

//UI content
const ExploreContainer: React.FC<ContainerProps> = ({ name }) => {
  return (
    <IonContent>
      <IonList>
        <IonItem>
          <IonLabel>DarkMode</IonLabel>
          <IonToggle id="IonToggleDarkMode" slot="end" checked={isChecked} onChange={() => darkModeToggle())} />
        </IonItem>
      </IonList>
    </IonContent>
  )
}
Nimantha
  • 6,405
  • 6
  • 28
  • 69
traxx2012
  • 394
  • 2
  • 16
  • Also I just realized when I set the toggles state like that, it permanently stays on and can't be switched [off, in this case]. So, how could I assign a checked state to the toggle while I'm at it without breaking it? – traxx2012 Oct 13 '20 at 16:53
  • Is this in a functional component or a class? (If it's in a functional component you would have to use the React hook useState and in a class the function setState()). – Zander Oct 13 '20 at 17:04
  • It's a functional component. Could you point me in some direction? Hooks are scary... – traxx2012 Oct 13 '20 at 17:06

2 Answers2

1

code

  const [checked, setChecked] = useState(false);

template

<IonToggle checked={checked} 
       onIonChange={(e) => setChecked(e.detail.checked)} />

Aaron Saunders
  • 33,180
  • 5
  • 60
  • 80
  • 1
    Sorry, what? As I said, I'm completely new to React and JS. Could you elaborate please? – traxx2012 Oct 13 '20 at 18:13
  • 3
    Code only answers are discouraged on SO. Explanations help visitors apply knowledge from your solution to their own issues, increase quality, and add long term value. Please consider adding context or explanation. – SherylHohman Oct 13 '20 at 20:13
  • I am going to leave this here and see how many people continue to come by and upvote the comment about "Code only answers are discouraged on SO"... really, one comment is enough? – Aaron Saunders Oct 20 '20 at 04:45
1

Since you have a functional component you have to use the useState hook to handle the state of your darkMode. In your JSX you use the state to handle the IonToggle (or the checkbox) by setting the isChecked state to the checked prop. Here is an example how you could do this with a simple checkbox:

const { useState } = React;

const DarkModeSwitch = () => {
  
    // here you set the initial state using the
    // useState hook:
    const [isChecked, setIsChecked] = useState(false);

    const darkModeToggle = () => {
    // toggle the state 'isChecked'
    // this makes it true if false and vice versa
    setIsChecked(!isChecked);
  }
  
    return (
    <div>
        <input 
        type="checkbox" 
        checked={isChecked} 
        onChange={() => darkModeToggle()} 
      />
    </div>
  )
}

Here is a working example: Codepen

Edit: Using your context-code it could look like this:

import React, { useState } from 'react';

const ExploreContainer: React.FC<ContainerProps> = ({ name }) => {

  // here you set the initial state using the useState hook:
  const [isChecked, setIsChecked] = useState(false);
  
  const darkModeToggle = () => {
    setIsChecked(!isChecked);
  }

  return (
    <IonContent>
      <IonList>
        <IonItem>
          <IonLabel>DarkMode</IonLabel>
          <IonToggle id="IonToggleDarkMode" slot="end" checked={isChecked} onChange={() => darkModeToggle())} />
        </IonItem>
      </IonList>
    </IonContent>
  )
}
Zander
  • 402
  • 1
  • 4
  • 17
  • Hey, thank you for the answer! I think I understand the concept. However, I see you included the return statement in your const. I'm working with the sidemenu-template and right now I have my logic above the `const ExploreContainer: React.FC` and inside that is the return statement where I built my interface. Where do I have to put your code in this case? And how would I call `darkModeToggle` to pass it my stored value? – traxx2012 Oct 13 '20 at 21:08
  • I don't really understand what you mean. Can you maybe provide some more code in your original post? I think 'const ExploreContainer: React.FC' is the equivalent to 'const DarkModeSwitch = () => {' just with TypeScript instead of plain JS (And with passing props). That would mean you would put the line where you set the initial state and the darkModeToggle function inside of it. – Zander Oct 13 '20 at 21:41
  • I've added the basic structure of my code to the original post. I've tried to add the hook etc. outside the functional component because I was afraid the return statement would mess with my UI. Now, for example the `darkModeToggle()` isn't available to the `IonSwitch` because it's a constant in another scope. But I can't figure out where to put the code you provided without it breaking the return statement of the ExploreContainer... – traxx2012 Oct 14 '20 at 09:37
  • 1. you should have posted a comment when you edited your code. You don't get notifications for edits on SO, but for comments you do :) 2. I've implemented your provided edit (thanks btw), but the toggle is now stuck to off and when you tap or click it, it doesn't change. – traxx2012 Oct 14 '20 at 11:37
  • I figured out the problem. The toggle keeps getting updated because I'm forcing React to re-render every 100ms (I need the interface to reflect changes to variables in real-time). Your solution was correct though, I'm grateful. – traxx2012 Oct 14 '20 at 14:57