0

Hey guys i am currently new at TypeScript and i am trying to have a state value that conatins only objects . At the moment i have an array of objects like this :

[{ Ananas: "A", Banana: "B" , Citroen: "C"}] 

, but the ultimate goal would be to have something like this :

{ Ananas: "A", Banana: "B" , Citroen: "C"}

I was defining my initial state like this

const [selectValue, setSelectValue] = useState<Array<string>>([]);

And now i try something like this , but i think is not the correct way to have initial state of objects only

 const [selectValue, setSelectValue] = useState({});

My update function is as simple as that

  const handleChange = (e: any) => {
  
    setSelectValue((selectValue: any) => {
      const newSelectValue = [...selectValue];
      if (!newSelectValue[0]) newSelectValue[0] = {};
      newSelectValue[0] = { ...newSelectValue[0], [e.target.value]: e.target.name };
      return newSelectValue;
    });
  };

But as i said from above i want to update the state value to contain only objects and not an array of objects . So i wonder how can i do that. Thanks upfront

PandaMastr
  • 687
  • 3
  • 14
  • 35

3 Answers3

1

Based on your explanation and my understanding your question, you can do something like this. If there's any problem, please say to contribute and improve the answer:

import "./styles.css";
import * as React from "react";

export default function App() {
  const [selectValue, setSelectValue] = React.useState({});
  const handleChange = (e: any) => {
    var index = e.nativeEvent.target.selectedIndex;
    console.log(e.nativeEvent.target[index].text);
    setSelectValue({
      ...selectValue,
      [e.target.value]: e.nativeEvent.target[index].text
    });
  };
  React.useEffect(() => {
    console.log(selectValue);
  }, [selectValue]);
  return (
    <div className="App">
      <select onChange={(e) => handleChange(e)}>
        <option value="A">Ananas</option>
        <option value="B">Banana</option>
        <option value="C">Citroen</option>
      </select>
    </div>
  );
}

Edit jovial-sun-w0z76

Majid M.
  • 4,467
  • 1
  • 11
  • 29
0

Just get first value from array.

let myArr = [{ Ananas: "A", Banana: "B" , Citroen: "C"}] 
let newArr = myArr[0]
console.log(newArr)

// { Ananas: 'A', Banana: 'B', Citroen: 'C' }
Jasur Kurbanov
  • 724
  • 2
  • 9
  • 20
  • Yeah , but the idea is on `handleChange` to create only objects and NOT an array of objects . Your way is a bit of workaround – PandaMastr Jul 27 '21 at 06:58
0

You should clean up your types first. It's very hard to follow what you are actually doing and where the problem is. Where is e.target.value coming from? What type is selectValue? Let TypeScript help you and don't fight it with :any ;)

If I got it right I would tackle it somehow like that


type Fruits = Record<'Ananas' | 'Banana' | 'Citroen', string>
export const OkCool = () => {
  const initialData: Fruits[] = [{ Ananas: 'A', Banana: 'B', Citroen: 'C' }]
  const [selectedValue, setSelectedValue] = useState<
    Record<string, Fruits> | undefined
  >()

  const selectFruit = (key: string, fruitsArray: Fruits[]) => {
    // destruct from Fruits[] to get Fruits
    const [fruits] = fruitsArray
    setSelectedValue(value => ({ ...value, [key]: fruits }))
  }

  return (
    <>
      <input
        placeholder="key"
        onChange={e => selectFruit(e.target.value, initialData)}
      />
      {JSON.stringify(selectedValue)}
    </>
  )
}