Home > Back-end >  How do you dynamically create useState variables in React?
How do you dynamically create useState variables in React?

Time:11-12

I am working on a React application that is essentially a virtual library of books. Users are able to view shelves that show what they are currently reading, have already read, want to read, etc.

As part of this application, I allow users to add a custom "shelf" that would display a new category of books (.e.g. "December Book Club", or "Audiobooks"). Each shelf that is rendered has its own state in order to keep track of which books belong to that collection.

How do I dynamically create useState varibles in React. For example, if the user input the name "Audiobooks", I want to create a new set of useState variables for that shelf :

const [audiobooks, setAudiobooks] = useState([]);

I'm having trouble with dynamically creating those variable names so that I can use them elsewhere in my code.

I have a function that accepts a camelcase name, and a startingValue.

const newStateVariable = (name, startingValue) =>{
  // prepend "set" to the name with first letter capitalized
  const setter = "set"   _.capitalize(name);

  const [ eval(name), eval(setter) ] = useState(startingValue);
}

However, this is apparently an invalid use of eval().

Expected: (inputs: "name=audiobooks", startingValue=[]) I want that line to evaluate to const [audiobooks, setAudiobooks] = useState([]); (inputs: name="julyBookClub", startingValue=[]) I want that line to evaluate to const [julyBookClub, setJulyBookClub] = useState([]); (inputs: name="myString", "") I want that line to evaluate to const [myString, setMyString] = useState("");

CodePudding user response:

So useState is essentially a React hook, and using that inside your newStateVariable method would obviously not work, hence there's no such way to 'create' a state variable on runtime.

Your question indicates there might be a better way to go about it - architecturally speaking.

Here's my suggestion - instead of creating a new state for a category (e.g, julyBook [which would cause a re-render anyway], why don't you add the category to a categories state variable? i.e, something like

const [category, setCategory] = useState([
    {
      name: "julyBook",
      // other properties
    },
    {
      name: "someOtherCategoryName",
      // properties
    },
  ]);
  • Related