Программное добавление компонентов с помощью React - PullRequest
0 голосов
/ 26 апреля 2019

Я довольно новичок в React и пытаюсь добавить новые компоненты к уже существующим, но я не уверен, как это сделать.

Итак, у меня есть список моих Seances и кнопка для добавления еще:
SeanceManager.js

return (
  <MDBRow>
    <MDBCol md="6">
      <MDBCard>
        <MDBCardBody>
          <form>
            <p className="h4 text-center py-4">Sign up</p>
            <div className="grey-text">
              <MDBInput
                label="Type your email"
                icon="envelope"
                group
                type="email"
                validate
                error="wrong"
                success="right"
              />
              <MDBInput
                label="Type your password"
                icon="lock"
                group
                type="password"
                validate
              />
            </div>
            <div className="text-center py-4 mt-3">
              <MDBBtn color="cyan" type="submit" onClick={props.submitLogin}>
                Log in
              </MDBBtn>
            </div>
          </form>
        </MDBCardBody>
      </MDBCard>
    </MDBCol>
  </MDBRow>
);

При нажатии на кнопку, чтобы добавить больше, появляется модальное представление и в конце оно имеетsubmit кнопка, которая должна добавить Seance.
AddSeanceModal.js

return (
  <Modal
    {...this.props}
    size="lg"
    aria-labelledby="contained-modal-title-vcenter"
    centered
  >
    <Modal.Header closeButton>
      <Modal.Title id="contained-modal-title-vcenter">Add Seance</Modal.Title>
    </Modal.Header>
    <Modal.Body>
      <div>
        <form>
          {/*First row*/}
          <MDBRow>
            <MDBCol md="4">
              <div className="custom-file">
                <input
                  type="file"
                  className="custom-file-input"
                  id="inputGroupFile01"
                  aria-describedby="inputGroupFileAddon01"
                />
                <label className="custom-file-label" htmlFor="inputGroupFile01">
                  Choose file
                </label>
              </div>
            </MDBCol>
          </MDBRow>

          {/*Second row*/}
          <MDBRow>
            <MDBCol md="4">
              <MDBInput
                onChange={this.changeHandler}
                type="text"
                id="materialFormRegisterPasswordEx4"
                name="algus_aeg"
                label="Algus Aeg"
                required
              />
            </MDBCol>
            <MDBCol md="4">
              <MDBInput
                onChange={this.changeHandler}
                type="text"
                id="materialFormRegisterPasswordEx4"
                name="lopp_aeg"
                label="Lõpp Aeg"
                required
              />
            </MDBCol>
          </MDBRow>

          {/*Third row*/}
          <MDBRow>
            <MDBCol md="4">
              <MDBInput
                onChange={this.changeHandler}
                type="text"
                id="materialFormRegisterPasswordEx4"
                name="aja_samm"
                label="Aja Samm"
                required
              />
            </MDBCol>
          </MDBRow>

          <Button variant="secondary" onClick={this.props.onHide}>
            Close
          </Button>
          <MDBBtn color="success" type="submit" className="float-right">
            Add Seance
          </MDBBtn>
        </form>
      </div>
    </Modal.Body>
  </Modal>
);

И, наконец, сам Seance:
Seance.js

return (
  <div
    className="card"
    style={{ marginBottom: "7px" }}
    onClick={() => this.setState({ modalShow: true })}
  >
    <div className="card-body">
      <h5 className="card-title">Seance nr: {this.props.id}</h5>
      <p className="card-text">Start aeg: {this.props.startDate}</p>
      <p className="card-text">End aeg: {this.props.endDate}</p>
      <button type="button" className="close float-right" aria-label="Close">
        <span aria-hidden="true">×</span>
      </button>
      <ResultModal id={1} show={this.state.modalShow} onHide={modalClose} />
    </div>
  </div>
);

Я также сделал скрипку в песочнице: https://codesandbox.io/s/qloo1vqr7j?fontsize=14

На данный момент у меня есть 4 статических Seances, но он должен начинаться с 0 и добавлять еще один разВы добавляете их.
Также X на Seance должен удалить его.

Я попытался создать список состояний в SeanceManager.js, но я не понял, как добавить компоненты в список из другого компонента AddSeanceModal.

1 Ответ

1 голос
/ 05 мая 2019

Существует несколько вариантов кода, которые удерживают ваше приложение от динамического.

Во-первых, вам нужно использовать container component, который обрабатывает все, что связано с состоянием Seance.Это включает в себя adding, removing и viewing.Все это должно быть обработано родителем, который обновляет свои дочерние элементы в соответствии с текущим значением в state.Пожалуйста, следуйте этому руководству, чтобы понять, контейнеры и компоненты .

Во-вторых, вам необходимо изменить способ использования Seances.Они должны храниться как array в пределах родительского state.Как он у вас есть, он жестко запрограммирован с 4 <Seances />, который не может быть удален / обновлен.

Вместо этого вы должны создать array из object s, как в state:

seances: [
  { id: "1", startDate: "2019-04-10 10:28:05.926-07", endDate: "2019-05-10 10:28:05.924-07" },
  { id: "2", startDate: "2019-04-11 11:28:05.926-07", endDate: "2019-05-11 11:28:05.924-07" },
  { id: "3", startDate: "2019-04-12 12:28:05.926-07", endDate: "2019-05-12 12:28:05.924-07" },
  ...etc
];

Вы будете использовать Array.map для отображения этих сеансов array и неявно return этих сеансов динамически (чтобы упроститьчитай, я пишу твой <Seance id={id} /> встроенный компонент):

<div>
  {seances.map(({ id, startDate, endDate }) => (
    <div key={id}>
     <h1>Seance nr: {id} </h1>
     <p>Start date: {startDate}</p>
     <p>End date: {endDate}</p>
     <button type="button" onClick={() => handleDeleteSeance(id)}>X</button>
    </div>
  ))}
</div>

Теперь ты удалишь эти элементы из массива seances, используя Array.filter для сеансаid собственность.Когда пользователь нажимает кнопку «X», он вызывает this.handleDeleteSeance с определенным сеансом id:

handleDeleteSeance = id => {
  this.setState(prevState => ({
    ...prevState, // spread out any previous state not related to "seances"
    seances: prevState.seances.filter(seance => seance.id !== id) // this translates to: compare each "seance" within "seances" and implicitly return any that do NOT match the "id" that was clicked
  })
};

Чтобы добавить элемент в массив seances, вы будете использовать оператор распространения и добавьте object со свойствами, которые были собраны из form:

handleSubmit = e => {
  e.preventDefault();
  const { id, startDate, endDate } = this.state;

  if (!id || !startDate || !endDate } return null; // if any properties are missing, don't add an item yet

  this.setState(prevState => ({
    ...prevState, // spread out any previous state not related to "seances"
    seances: [...prevState.seances, { id, startDate, endDate } ] // this translates to: spread out any previous seances and add a new object with "id", "startDate" and "endDate"
  });  
} 

Пример работы с массивами (поскольку это клиент-только в реализации, я решил фильтровать по позиции массива, чтобы мне не приходилось иметь дело с генерацией уникальных id с, однако вы можете использовать uuid для генерации этих динамических id с, еслиВы хотите):

Edit Class Component - Filter Data by Array Index


Другие примечания :

  • Один из ваших компонентовсодержит let modalClose = () => this.setState({ modalShow: false }); в методе render.Это недопустимо и должно быть определено как метод класса.
  • Структурируйте ваши компоненты для повторного использования.У вас есть некоторые компоненты, которые есть, но затем у вас есть некоторые, которые находятся в другом компоненте (например, FileInput).По мере роста вашего приложения вам может понадобиться использовать FileInput в другом месте для другой формы.
  • Использовать синтаксис ES6 во всем вашего проекта, чтобы упростить ваш код.Например, вы можете деконструировать props для вашего Login компонента следующим образом: const Login = ({ submitLogin }) => ( <MDBRow>...etc</MDBRow>);.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...