0

This is probably a basic question but,

I have two useState variables:

const [varOne, setVarOne] = useState(null);
const [varTwo, setVarTwo] = useState(null);

And a third variable that tells me which variables I need to use, varOne or varTwo:

const [whichVar, setWhichVar] = useState(0);

And I have a third variable curVar which will be either varOne or varTwo based on the value of whichVar:

const [curVar, setCurVar] = useState(null);
if (whichVar === 0) {
  curVar = varOne;
  setCurVar = setVarOne;
} else {
  curVar = varTwo;
  setCurVar = setVarTwo;
}

I realize this is probably wrong, but in another post I was told I could use useReducer to achieve this, what is the most elegant way to achieve this with useReducer?

Ken
  • 1,155
  • 2
  • 19
  • 36
  • I don't really get this use case. You already have both values and another to tell you which to use. Why do you need a 4th that duplicates one of the original 2 values? Just use that original state value. – Jayce444 May 19 '21 at 02:11
  • Its just annoying that every time I want to use one of these variables I need to go through the whole process of checking which variable to use and it gets very messy. It'd be nicer if I could just do it once in one place – Ken May 19 '21 at 02:15
  • I can tailor my answer more to your use case if you can provide examples of how you’re using this, for example, is it all in the same component? – Steve Freed May 19 '21 at 02:25

2 Answers2

3

Well a simple way would be to use a custom hook that stores all the state/logic and returns the currently active value. For instance:

import React, { useState } from 'react';

const useSwitchValue = () => {
  const [varOne, setVarOne] = useState('A');
  const [varTwo, setVarTwo] = useState('B');
  const [whichVar, setWhichVar] = useState(0);

  if (whichVar === 0) return {
    value: varOne,
    setVarOne,
    setVarTwo,
    switchVars: () => setWhichVar(whichVar ? 0 : 1)
  };
  else return {
    value: varTwo,
    setVarOne,
    setVarTwo,
    switchVars: () => setWhichVar(whichVar ? 0 : 1)
  };
};

export default function App() {
  const { value, switchVars, setVarOne, setVarTwo } = useSwitchValue();

  return (
    <div>
      <button onClick={switchVars}>
        SWITCH VALUES
      </button>
      <div>{value}</div>
    </div>
  );
}

With this hook, you can change the state values and switch between them, but when you want to use the currently selected value, you just refer to {value} without having to do any conditional checking (cos that's done once, inside the custom hook).

Sandbox

Jayce444
  • 8,725
  • 3
  • 27
  • 43
1

Yes useReducer can help achieve similar functionality. useReducer will emit your current state and a dispatch function based on a given reducer and initial state. You then use this dispatch method to dispatch types of actions that are specified in your reducer function to manipulate your state. Check out the first example in the React docs, they’re very helpful https://reactjs.org/docs/hooks-reference.html#usereducer

Steve Freed
  • 91
  • 1
  • 11
  • Thanks, yes I'd love a specific example for this case. I've never really used useReducer and have read through the docs but don't know how to apply it in this case. It is all in the same component. – Ken May 19 '21 at 02:49