ReactJS |Компонент для получения реквизитов в виде постоянных или серверных значений с обещаниями - PullRequest
0 голосов
/ 19 декабря 2018

Я сделал небольшой компонент многократного использования из Formik.Это довольно просто.Пример библиотеки послужит хорошей отправной точкой, поэтому я поделюсь им ниже, а также URL:

Код Песочница для примера Formik

<code>import React from "react";
import { render } from "react-dom";
import { Formik, Field } from "formik";

function Checkbox(props) {
  return (
    <Field name={props.name}>
      {({ field, form }) => (
        <label>
          <input
            type="checkbox"
            {...props}
            checked={field.value.includes(props.value)}
            onChange={() => {
              if (field.value.includes(props.value)) {
                const nextValue = field.value.filter(
                  value => value !== props.value
                );
                form.setFieldValue(props.name, nextValue);
              } else {
                const nextValue = field.value.concat(props.value);
                form.setFieldValue(props.name, nextValue);
              }
            }}
          />
          {props.value}
        </label>
      )}
    </Field>
  );
}

function App() {
  return (
    <Formik
      initialValues={{
        roles: ["admin"]
      }}
      onSubmit={values => alert(JSON.stringify(values, null, 2))}
    >
      {formik => (
        <div>
          <div>
            <Checkbox name="roles" value="admin" />
            <Checkbox name="roles" value="customer" />
          </div>
          <button onClick={formik.submitForm}>submit</button>
          <pre>{JSON.stringify(formik.values, null, 2)}
)} );} render (, document.getElementById ("root"));

Я передаю вместо жестко закодированных значений реквизит Checkbox, который имеет строку (используя PropTypes).Этот реквизит-заполнитель затем заполняется значениями, которые я передаю ему, в зависимости от использования из файла Constants.js следующим образом.

const NameForCheckbox = {
  Name1: 'Value1',
  Name2: 'Value2',
  Name3: 'Value3',
};

export default NameForCheckbox; // Tha is working just fine.

Проблема: Мы могли бы получить в будущем этоинформация от Server Payload.Это сделает мой подход устаревшим, поэтому, чтобы проверить его в будущем, я хочу, чтобы он отображал либо мои данные, если нет данных на сервере, либо обходил их, если есть значения сервера.

Теперь я читало том, как это сделать, и я обнаружил, что Promises способен решить мою проблему.Я пробовал разные вещи, которые не буду перечислять здесь, как я выяснил из других ответов в Stack Overflow, чтобы они не были правильными.Буду признателен, если вы поможете мне здесь.

МОЯ НАСТРОЙКА: До сих пор я делал это, что могло быть совершенно неприменимо, но я перечислю это.

Я создаю 3 Действия, используя приставку (GetDataAttempt, GetDataSucces, GetDatFailure).Который в ответ делает запрос GET к этой конкретной конечной точке.Это, в свою очередь, будет использовать некоторые функции RxJS, например

import { of } from 'rxjs';
import { switchMap, map, catchError } from 'rxjs/operators';

import { observableFromHttpPromise, combineAndIsolateEpics } from 'utilities/epicsUtil';
import { Type, Actions } from '../actions';

const getDataEpic = (action$, store, deps) =>
  action$.ofType(Type.GET_DATA_ATTEMPT).pipe(
    switchMap(() =>
      observableFromHttpPromise(deps.getData()).pipe(
        map(result => Actions.getDataSuccess(result && result.data)),
        catchError(error => of(Actions.getDataFailure(error && error.message)))
      )
    )
  );

const getAllEpics = combineAndIsolateEpics(getDataEpic);

export default getAllEpics;

Наконец, редукторы отправят полезную нагрузку компоненту, который я прочитал с помощью MapStateToProps, или пустую строку.

Теперь к хитрой части и причине, которую я спросил. Как применить эту условную логику к компонентам с помощью Promises . Или что-нибудь еще.

1 Ответ

0 голосов
/ 23 декабря 2018

Я не уверен, что понимаю, как много здесь меняются обещания.

Если я правильно вас понимаю, вы хотите отображать статический контент в NameForCheckbox, если не существует какой-либо информации о сервере.Очевидно, что выборка этой информации асинхронна.

Самой простой реализацией будет отправка вашего запроса API (возможно, через действие), когда компонент монтируется.В то же время вы можете отобразить значения в NameForCheckbox, используя некоторую простую условную логику для отображения либо данных API, если они существуют, либо флажка в противном случае.

import NameForCheckbox from './NameForCheckbox';

class Checkboxes extends React.Component {

  componentDidMount = () => {
    // dispatch async action here that will eventually populate the
    // apiData prop below
  }

  renderCheckboxes = data => {
    // insert rendering logic here
  }

  render() {
    const { apiData } = this.props;
    const data = someData || NameForCheckbox;

    return this.renderCheckboxes(data);
  }
}

const mapStateToProps = state => ({
  apiData: state.reducer.data || null;
})

Обратите внимание, как data падает доданные по умолчанию, когда apiData ложно (как и null или '', как вы и предполагали), но когда данные из API существуют в состоянии, они будут отображаться вместо этого.

Это такжедовольно часто устанавливается анимация загрузки при ожидании возврата данных, поэтому вы также можете начать с начального состояния loading = true, а затем установить loading = false, когда действие API успешно завершится.

// In reducer
const initialState = {
  loading: true,
  apiData: null
}

// In component
render() {
  const { apiData, loading } = this.props;

  if (loading) return <Loading />;

  return this.renderCheckboxes(apiData);
}
...