简体   繁体   中英

In React, How to pass the selected dropdown data to state

I have been trying to make a multi-select dropdown for my project, where a person can select which school subjects they teach at the website's registration. But I have been having troubles in regards of passing the selected value to the declared state in a simple-option dropdown.

When I try to make the POST request to my API (made with NodeJS, express and mongoDB for database), the console.log returns that the subject object has three arrays with all the subject data. I want to pass only the _id field, since it was what was requested.

How should I get only the subjects _id when my API GET request returns all fields?

Code for reference:

API call

async function listActiveSubjects() {
    const response = await api.get("/subject");
    return response.data;
}

JSON returned from the request:

{
  "subjects": [
     {
            "isActive": true,
            "_id": "6001e71606a211004877f6e1",
            "name": "Subject 1",
            "description": "Subject 1 description",
            "__v": 0
      },
      {
            "isActive": true,
            "_id": "6001e71606a211004877f6e1",
            "name": "Subject 2",
            "description": "Subject 2 description",
            "__v": 0
      },
  ]
}

React functional component:

import React, { useState, useEffect } from 'react';

import { listActiveSubjects } from '../../../../services/subjects';

const TeacherClassInfo = props => {
    const [subjects, setSubjects] = useState();
    const [selected, setSelected] = useState({ _id: ''})

    const handleListActiveSubjects = async () => {
        const getSubjects = await listActiveSubjects();
        setSubjects(getSubjects);
    }

    useEffect(() => {
        handleListActiveSubjects()
    }, []);

    const onChange = (key, _id) => {
        setSelected(() => ({
            [key]: _id,
        }))
    }

    return(
        <select>
          {subjects &&
            subjects.subjects.map((subjects) => {
              return (
                <option
                  onChange={_id => onChange(_id)}
                    key={subjects._id}
                    value={selected[subjects._id]}>
                      {subjects.name}
                 </option>
              );
           })
         }
      </select>  
    );

The output that the log shows is:

subjects: Array(2)
    0: {isActive: true, _id: "6001e71606a211004877f6e1", name: "Subject 1", description: "Subject 1 
description", __v: 0}
    1: {isActive: true, _id: "6001e73106a211004877f6e2", name: "Subject 2", description: "Subject 2 description", __v: 0}
length: 2

And in my understanding it should be:

subjects: Array(1)
    0: {_id: "6001e71606a211004877f6e1"}
length: 1

, as is configured on the database.

From other tutorials and questions I saw here, this was supposed to set the selected id, but unfortunately it hasn't been working as expected. Any help would be really appreciated

You can return all the _id values in an array by using the map() method on the response.data.subjects array. This will loop over each subject and will create a new array based on the values returned in the callback. In this case it's the _id property value.

async function listActiveSubjects() {
  const response = await api.get("/subject");
  const ids = response.data.subjects.map(({ _id }) => _id);
  return ids;
}

This will result in:

[
  "6001e71606a211004877f6e1",
  "6001e73106a211004877f6e2",
]

Giving you only the strings that you need.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM