Использовать состояние с объектами в качестве опций в выпадающем меню: РЕАГИРОВАТЬ

#javascript #html #reactjs #dropdown

#javascript #HTML #reactjs #выпадающий

Вопрос:

Создание фиктивного веб-сайта с несколькими функциональными аспектами. Просто для пояснения, я начал изучать React неделю назад, поэтому, пожалуйста, будьте добры с вашими ответами. Спасибо!

Изначально созданное состояние в App.js это позволяет мне добавлять и удалять клиентов. (как в банальном списке дел)

Теперь, используя другой компонент, где я могу «добавить урок», я хочу иметь выпадающий селектор, где я могу выбрать одного из существующих клиентов из другого состояния в качестве своего варианта. На данный момент я создал все, что принимает входные данные, и console.log() показывает, что все проходит нормально. Однако, похоже, я не могу заставить выпадающие параметры отображаться как существующие клиенты, чтобы я мог добавить урок в другом состоянии. Чтобы уточнить, у меня есть 2 состояния, клиенты и уроки (с существующими клиентами).

Вот мой App.js

 import React, { Component } from 'react'
import Clients from './components/Clients'
import AddClient from './components/AddClient'
import NavBar from './components/NavBar'
import AddLesson from './components/AddLesson'

    class App extends Component {
      state = {
        clients : [
          {id : 1 , name : 'bob', price : 30},
          {id : 2 , name : 'mary', price : 40},
          {id : 3 , name : 'greg', price : 45}
        ],
        lessons : [
          {id: null, name: '', time: null}
        ]
      }

      deleteClient = (id) => {
        let clients = this.state.clients.filter(client => {
          return client.id !== id
        })
        this.setState({
          clients: clients
        })
      }

      addClient = (newClient) => {
        newClient.id = Math.random();
        let clients = [...this.state.clients, newClient];
        clients.sort((a, b) => a.name.localeCompare(b.name))
        this.setState({
            clients: clients,
        })
      }

      addLesson = (newLesson) => {
        newLesson.id = Math.random(); 
        let lessons = [...this.state.lessons, newLesson];
        this.setState({
            lessons: lessons,
        })
        console.log(lessons)
      }

      render() {
        return (
          <div className="App">
            <NavBar/>
            <Clients clients={this.state.clients} deleteClient={this.deleteClient}/>
            <AddClient addClient={this.addClient}/>
            <AddLesson addLesson={this.addLesson}/>
          </div>
        );
      }
    }

    export default App;
  

Вот AddLesson.js

 import React, {Component} from 'react'

class AddLesson extends Component {
    state = {
        lessons: [
            {id : null, name: '', time: null}
        ]
    }

    handleChange = (e) => {
        this.setState({
            [e.target.id] : e.target.value
        })
    } 

    handleSubmit = (e) => {
        e.preventDefault();
        this.props.addLesson(this.state);
        e.target.reset();
    }

    render() {
        return (
            <div className="text-center">
                <h2>Add a lesson</h2>
                <form onSubmit={this.handleSubmit}>

                    <select name="lesson_client">
                        <option>{this.props.clients}</option>
                    </select>

                    {/* <label htmlFor="name">Client Name: </label>
                    <input type="text" id="name" onChange={this.handleChange}/><br/>
                    <label htmlFor="time">Lesson Duration (in hours): </label>
                    <input type="text" id="time" onChange={this.handleChange}/><br/>
                    <button className="btn btn-primary">Add Client</button> */}
                </form>
            </div>
        )
    }
}

export default AddLesson
  

Я старался не перегружать код, поэтому, если я чего-то не хватает, пожалуйста, дайте мне знать, и я отредактирую это.

Комментарии:

1. У меня также есть Clients.js это фактически отображает пользователю список клиентов. Если это необходимо, я также могу опубликовать это.

2. Извините, чтобы понять, вы пытаетесь отобразить список клиентов внутри AddLesson компонента? Если это так, вы не передаете клиентов в качестве поддержки.

3. Вы ищете: reactjs.org/docs/lists-and-keys.html

4. @Kurtis да, я хочу, чтобы список клиентов отображался в качестве опций в выпадающем списке. Я думал, что, поскольку AddLesson.js является ли компонент, основанный на классе, реквизитами, которые передаются автоматически?

5. Автоматически передается только материал React. Вам нужно сделать две вещи. Сначала добавьте ` <AddLesson addLesson={this.addLesson} clients={this.state.clients} />` в App.js . Во-вторых, вам нужно сопоставить клиенты, как Avanthika ответила ниже.

Ответ №1:

Вам нужно перебирать клиентов и отображать их.

 <select onChange={(e) => this.handleChange(e)} name="lesson_client">
  {this.props.clients.map(client => <option key={client.id} value={client.price}>{client.name}</option>)}
</select>
  

Вы можете прослушать handleChange , чтобы прочитать выбранное значение. (Примечание: я изменил e.target.id на e.target.name , поскольку в теге select нет идентификатора attr)

 handleChange = (e) => {
  this.setState({
    [e.target.name] : e.target.value
  })
} 
  

И я также заметил, что вы не переходите clients к AddLesson компоненту. Пожалуйста, передайте это, чтобы код заработал.

<AddLesson clients={this.state.clients} addLesson={this.addLesson}/>

Комментарии:

1. Он не использует эту handleChange функцию для выпадающего списка. Это используется в текстовых полях, которые закомментированы, поэтому изменение идентификатора приведет к их нарушению. Приятные правки после моего комментария выше 🙂

2. Умм да, только что заметил прокомментированный код, он может повторно использовать handleChange с атрибутом name!

3. вопрос: где в <select></select> находится [e.target.name] ?

4. Attr name=»lesson_client» должен сделать это за вас! <select name="lesson_client"></select>