Используя Unstated с TypeScript и React, как получить экземпляр типизированного контейнера внутри дочерних элементов <Subscribe>? - PullRequest
0 голосов
/ 15 сентября 2018

В моем приложении React я использую Unstated для управления общим состоянием, но я сталкиваюсь с проблемой при использовании этого с TypeScript: компонент <Subscribe> передает мне экземпляр моего состояния, который напечатано как Container<any>. Это означает, что он должен быть приведен к моему типу, например Container<MyState>, прежде чем я смогу безопасно использовать его.

Если бы вместо этого я хотел, чтобы Unstated передал мне уже набранный экземпляр моего контейнера, как мне обернуть и / или разветвить Unstated source и / или его файл набора , так что когда я получаю экземпляр Container, он печатается как Container<MyState>?

Кстати, особая причина, по которой я хочу получить переданный типизированный контейнер, заключается в том, что я могу использовать деструктурирование сложного состояния, не переключаясь на использование блочной функции жирных стрелок, которая является гораздо более многословной.

Вот упрощенный пример кода, который я хотел бы написать:

function Counter() {
  return (
    <Subscribe to={[CounterContainer]}>
      {({increment, decrement, state}) => (
        <div>
          <button onClick={() => decrement()}>-</button>
          <span>{state.count}</span>
          <button onClick={() => increment()}>+</button>
        </div>
      )}
    </Subscribe>
  );
}

А вот текущий способ, которым я пишу это, в упрощенном неустановленном примере с использованием TypeScript:

import React from 'react';
import { render } from 'react-dom';
import { Provider, Subscribe, Container } from 'unstated';

interface CounterState {
  count: number
};

class CounterContainer extends Container<CounterState> {
  public state = {
    count: 0
  };

  public increment() {
    this.setState({ count: this.state.count + 1 });
  }

  public decrement() {
    this.setState({ count: this.state.count - 1 });
  }
}

function Counter() {
  return (
    <Subscribe to={[CounterContainer]}>
      {(counter: CounterContainer) => {
        const {increment, decrement, state} = counter;
        return (
          <div>
            <button onClick={() => increment()}>-</button>
            <span>{state.count}</span>
            <button onClick={() => decrement()}>+</button>
          </div>
        )
      }}
    </Subscribe>
  );
}

render(
  <Provider>
    <Counter />
  </Provider>,
  document.getElementById('root')
);

1 Ответ

0 голосов
/ 16 сентября 2018

Итак, взглянув на PR , который первоначально добавил определение машинописного текста, мы заметили, что они не смогли найти способ автоматически предоставить типизацию, которую вы ищете, поскольку что-то вроде $TupleMap не существует в TS, как в Flow, и вместо этого вам придется вручную вводить текст.

Если ваша основная мотивация - избежать лишних {} с помощью функции стрелки, вы можете вручнуюобеспечить печатать и по-прежнему делать то же самое деструктурирование.Итак, из вашего примера:

function Counter() {
  return (
    <Subscribe to={[CounterContainer]}>
      {({increment, decrement, state}: CounterContainer) => (
          <div>
            <button onClick={() => increment()}>-</button>
            <span>{state.count}</span>
            <button onClick={() => decrement()}>+</button>
          </div>
        )
      }
    </Subscribe>
  );
}

также работает.Может быть, есть способ напечатать это автоматически в Typescript, но это вне моего понимания.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...