This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Select from 'react-select'; | |
import type { ComponentProps } from 'react'; | |
@Component({ | |
standalone: true, | |
imports: [CommonModule, ReactComponentDirective], | |
template: ` | |
<h1>Todos page</h1> | |
<button (click)="changeProps()">Change</button> | |
<div [reactComponent]="Select" [props]="selectProps"></div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { ComponentProps, createElement, ElementType } from 'react'; | |
import { createRoot } from 'react-dom/client'; | |
@Directive({ | |
selector: '[reactComponent]', | |
standalone: true | |
}) | |
export class ReactComponentDirective<Comp extends ElementType> { | |
@Input() reactComponent: Comp; | |
@Input() props: ComponentProps<Comp>; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function ShopTotal() { | |
const total = useShopSelector(selectTotal); | |
return <p>{total}</p> | |
} | |
function ShopItems() { | |
const items = useShopSelector(selectShopItems); | |
return items.map(...); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { createSelector } from 'reselect' | |
import { createSelectorHook, createStore } from './store'; | |
interface ShopState { | |
taxPercent: number; | |
items: Array<{ name: string, value: number }> | |
} | |
const selectShopItems = (state: ShopState) => state.items | |
const selectTaxPercent = (state: ShopState) => state.taxPercent |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { randText } from '@ngneat/falso'; | |
import { addTodo } from './todos.store'; | |
function Todos() { | |
const todos = useTodosSelector(state => state.todos); | |
return <> | |
{todos.map(({ title, id }) => <p key={id}>{title}</p>)} | |
<button onClick={() => addTodo(randText())}>Add todo</button> | |
</> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { randUuid } from '@ngneat/falso'; | |
import { createSelectorHook, createStore } from './store'; | |
type TodosState = { | |
filter: 'ALL' | 'ACTIVE'; | |
todos: Array<{ id: string, title: string }> | |
} | |
export const todosStore = createStore<TodosState>({ | |
todos: [], |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export function createSelectorHook<State extends Record<string, any>>( | |
store: Store<State> | |
) { | |
return function useSelector<R>(selector: (state: State) => R = | |
(state) => state as R): R { | |
let currentState = useRef<R>(selector(store.getValue())); | |
const getSnapshot = () => selector(store.getValue()) | |
return useSyncExternalStore( |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
type TodosState = { | |
filter: 'ALL' | 'ACTIVE'; | |
todos: Array<{ id: string, title: string }> | |
} | |
export const todosStore = createStore<TodosState>({ | |
todos: [], | |
filter: 'ALL' | |
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export function createStore<State extends Record<string, any>>(state: State) { | |
return new Store(state); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export class Store<State extends Record<string, any>> { | |
private subscribers = new Set<Subscriber<State>>(); | |
constructor(private state: State) { } | |
getValue() { | |
return this.state; | |
} | |
setValue(newState: State | ((state: State) => State)) { |