В моем приложении 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')
);