Встраивание в массив объектов с помощью помощника обновления setState и целей событий работает только с начальным индексом массива и завершается неудачно со всеми остальными. - PullRequest
0 голосов
/ 18 апреля 2020

Я пытаюсь создать приложение, которое будет устанавливать setState на основе входных данных выбора формы с помощью обработчиков onChange. Мое состояние - это массив объектов, и мои входные данные выбора формы создаются путем сопоставления другого массива объектов для установки различных атрибутов формы, которые я буду использовать, чтобы определить, где и что встраивается в массив состояния.

По какой-то причине мой код работает с первой отображенной формой, но не работает на всех остальных. Вот мой код:

import React, { Component } from 'react'
import { draft_teams } from '../utils/draftinputs';
import { getPlayers } from '../actions/playerActions';
import { saveDraftboard } from '../actions/draftActions';
import { connect } from 'react-redux';
import { 
    Form,
    Col,
    Button,
    } from 'react-bootstrap';
import PropTypes from 'prop-types';
import update from 'immutability-helper';

class DraftForm extends Component {

state = {
        draftboard: [
            {
                1: {team:'', player: ''}
            },
            {
                2: {team:'', player: ''}
            },
            {
                3: {team:'', player: ''}
            },
            {
                4: {team:'', player: ''}
            }
       ]
}

onChange = (e) => {
        e.persist();
        const pickName = e.target.name
        const pickValue = e.target.value
        const pickObjectName = e.target.getAttribute('label')
        this.setState((prevState) => update(prevState, { draftboard: [{ [pickObjectName]: 
        {[pickName]: {$set: pickValue}}}]} ))            
     }

render() {

        const { players } = this.props.player;

        return (
            <div className='mt-5'>
                <h5 className='mb-3 text-center'>Set Draft Board</h5>
                <Form onSubmit={this.onSubmit}>
                    {draft_teams.map(( { pick, name, player }) => (
                        <Form.Row>
                        <Form.Group as={Col} sm={.5} controlId="formGridPosition">
                            <Form.Label>Pick #</Form.Label>
                                <Form.Control   
                                defaultValue={pick}
                                className='mb-2'
                                size='sm'
                                name='pick'
                                label={pick}
                                as="select" >
                                <option>{pick}</option>
                                </Form.Control>
                            </Form.Group>

                            <Form.Group as={Col} controlId="formGridPosition">
                            <Form.Label>Team</Form.Label>
                                <Form.Control   
                                onChange={this.onChange}
                                defaultValue={name}
                                label={pick}
                                size='sm'
                                className='mb-2'
                                name='team'
                                as="select">
                               {draft_teams.map(({ name }) => (
                                   <option>{name}</option> 
                               ))}   
                            </Form.Control>
                            </Form.Group>

                            <Form.Group as={Col} controlId="formGridPosition">
                            <Form.Label>Player - Consensus Pick {pick} - {player}</Form.Label>
                                <Form.Control   
                                onChange={this.onChange}
                                size='sm'
                                defaultValue={player}
                                className='mb-2'
                                name='player'
                                label={pick}
                                as="select">
                                {players.map(({ name }) => (
                                        <option>{name}</option>          
                            ))}
                            </Form.Control>
                            </Form.Group>
                    </Form.Row>
                    ))}

                    <Button 
                        className='mb-5'
                        variant="success"
                        type="submit"
                        block
                        >Save Draft Board
                    </Button>
                </Form>
            </div>
        )
    }
}

DraftForm.propTypes = {
    player: PropTypes.object.isRequired,
    getPlayers: PropTypes.func.isRequired
}

const mapStateToProps = state => ({
    player: state.player
})

export default connect(mapStateToProps, { getPlayers })(DraftForm)

Странно, он отлично работает с самой первой формой, но не работает со всеми остальными, и я получаю сообщение об ошибке, указывающее, что события не определены. Кто-нибудь знает, почему это происходит? Спасибо! Ошибка здесь

РЕДАКТИРОВАТЬ: Включен полный код класса по запросу

1 Ответ

0 голосов
/ 19 апреля 2020

Вы должны использовать $merge вместо $set.

$set заменить объект

$merge заменить или добавить свойство, но сохранить свойства объекта

Но проблема в том, что вам нужно включить позицию в массив, возможно вам понадобится, чтобы draftboard был бы объектом вместо массива:

Я дам оба решения:

  • Продолжите с эта структура:
// state structure
state = {
        draftboard: [
            {
                1: {team:'', player: ''}
            },
            {
                2: {team:'', player: ''}
            },
            {
                3: {team:'', player: ''}
            },
            {
                4: {team:'', player: ''}
            }
       ]
}

// Test it in componentDidMount and it works
componentDidMount() {
    // this will change position 0 in `draftboard` and key 1 inside the object
    this.setState(
      prevState =>
        update(prevState, {
          draftboard: {
            0: {
              1: {
                $merge: {
                  team: "hey"
                }
              }
            }
          }
        }),
      () => {
        // this will change position 1 in `draftboard` and key 2 inside the object
        this.setState(prevState =>
          update(prevState, {
            draftboard: {
              1: {
                2: {
                  $merge: {
                    team: "how"
                  }
                }
              }
            }
          })
        );
      }
    );
  }

  • Изменить на объект:

// state structure
 state = {
    draftboard: {
      1: { team: "", player: "" },
      2: { team: "", player: "" },
      3: { team: "", player: "" }
    }
  };

// Test it in componentDidMount and it works
componentDidMount() {
    this.setState(
      prevState =>
        update(prevState, {
          draftboard: {
            1: {
              $merge: {
                team: "team1"
              }
            }
          }
        }),
      () => {
        this.setState(prevState =>
          update(prevState, {
            draftboard: {
              1: {
                $merge: {
                  player: "team1"
                }
              }
            }
          })
        );
      }
    );
  }

Теперь, если вы хотите изменить свойства числа во втором примере на строки, окончательно структура

// state structure
 state = {
    draftboard: {
      pick1: { team: "", player: "" },
      pick2: { team: "", player: "" },
      pick3: { team: "", player: "" }
    }
  };
// update structure

// We will change property player of key `pick1` in draftboard
this.setState(prevState =>
    update(prevState, {
        draftboard: {
            ['pick1']: {
             $merge: {
                player: "team1"
              }
            }
         }
     })
);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...