Code Monkey home page Code Monkey logo

legend-state's People

Contributors

bevvvis avatar bram209 avatar c41m50n avatar cabello avatar chakravarthi-bb avatar chakrihacker avatar danielmoraes avatar fahmitech avatar gamtiq avatar gifarina avatar hzoo avatar jamonholmgren avatar jmeistrich avatar karibash avatar kieran-osgood avatar lishine avatar manc avatar manolotonto1 avatar matthewmturner avatar minorgod avatar mlynchdev avatar promontis avatar scottawesome avatar sheldon-welinga avatar stitifatah avatar yujian920 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

legend-state's Issues

Docs: How does this compare to mobx?

I'm seeing alot of similarities between this library and mobx, and I'm wondering what the future holds in this regard. (I admit I thought it was going to be based on rxjs style observables due to the nomenclature, but digging in further it appears to be very mobx-ish)

I think it would be good to compare the two, since the core APIs appear to be similar, and I even see some Flow constructs like mobx uses.

Curious if that was a source of inspiration here!

How to create an Elm like hook?

Hello, I'm wondering how I could leverage this project to create an Elm style (or reducerlike) hook.

Something along the lines of:

import { useObservable, enableLegendStateReact } from "@legendapp/state/react";
import { useRef } from "react";

enableLegendStateReact();

const useLegendaryHook = (init, update) => {
  const model = useObservable(init());

  const dispatch = (msg: any) => {
    const nextModel = update(msg, model.get());
    model.set(nextModel);
  };

  return [model.get(), dispatch];
};

const init = () => 0;
const update = (msg, model) => {
  if (msg && msg.type === "increase") {
    return model + 1;
  } else {
    return model;
  }
};

export default function App() {
  const renderCount = ++useRef(0).current;

  const [model, dispatch] = useLegendaryHook(init, update);

  // Text element re-renders itself
  return (
    <>
      <div>Renders: {renderCount}</div>
      <div>Count: {model}</div>
      <button onClick={() => dispatch({ type: "increase" })}>click</button>
    </>
  );
}

The model type in this simple example is just a number and my reducer function update takes in a message and creates a new model based on the received msg.

In this example, I get two new renders for each click, so I'm most likely missing the point somewhere.

Any thoughts on this?

issue with typescript strict mode and observable primitives

when exporting an observable from a module typescript (strict mode) complians about not being able to name used types

ie
export const valid = observable(true)

gives the below error:

image

exporting the types makes this error go away:

export interface ObservablePrimitiveFnsBase extends ObservableBaseFns {
set(value: T | ((prev: T) => T)): ObservablePrimitiveChild;
}
export interface ObservablePrimitiveFnsBoolean {
toggle(): T;
}

`getPrevious` does not work for Array changes

First, thank your for your great work! I'm currently trying to integrate this library into my new web app – and trying to get my head around the concept/usage and the types. I do have a few issues understanding, but one thing at a time. I'm using React.

I have an Array of items that can be rearranged by the user. I use state.onChange and its getPrevious() function to look for certain changes. If I deal with content changes (e.g. strings), getPrevious() works as expected, giving me the state as it was before the change. However, when changing the order of Array items, the result of getPrevious() and the current state are the same.

I have created a Sandbox example. To verify the issue, please click the Up and Down buttons to rearrange the items, and check the Console logs; before/after should be different, but are equal.

Does it work with react-query?

Hi. Great library!

I saw your fetch example in the docs which uses the useObservable hook and fetch.
Any way to employ this with react-query's useQuery and other hooks?

react 18

Hi Jay, does the library work with react 18 concurrent features? Are there any problems?

Encountered two children with the same key

Hello,
I've noticed when using Legend that if I render (in React Native) a Text element with two pieces of state from an observable, I get a warning that two children with the same key were found:

<Text>{user.firstname} {user.lastname}</Text>

They key that it warns about is an empty string and there's only one text element, but I think it has to do with how React Native virtualizes text components (so the two parts of the name become two virtual text elements). Does Legend do something involving keys when rendering? If I remove the lastname bit from the above or if I replace it with any two pieces of static text, there's no warning. There's also no warning if I call get on each of the name pieces so it seems to have something to do with the auto-rendering. It'd be nice if I didn't have to sometimes call get and sometimes not, as this'll confuse my team a lot :)

Wrapping observable.set within startTransition breaks atomic updates

Hi! legend-state is fantastic, and I love it!

I've been playing with your demo on codesandbox and found that wrapping count.set(...) in startTransition(means enabling concurrent mode) breaks atomic updates: link.

CleanShot.2022-10-07.at.12.00.17.mp4

I attached a video showing that components rerender four times each time the count updates.

Is it intended? Any plans for supporting concurrent rendering?

Thanks!

Fast Refresh oddities

"react-native": "0.70.2",
"@legendapp/state": "^0.19.0",
"react": "18.1.0",
"typescript": "^4.8.2"

I'm noticing observers being called an increasing number of times after fast refresh.

After a fresh reload I get the logs:

ComponentA hook observer undefined
ComponentA hook observer 1665157345629

if I save ComponentA.tsx without making any changes fast refresh triggers and I get an addditional single console.log:

ComponentA hook observer 1665157345629

If I then go and save ComponentB.tsx without making any changes fast refresh triggers and I get 2 console.logs with newer timestamps

ComponentA hook observer 1665157432979
ComponentA hook observer 1665157432979

If I then go back to save ComponentA.tsx again and save without making any changes I get an addditional single console.log:

ComponentA hook observer 1665157432979

Then if I go back and save ComponentB.tsx without making any changes, I get 3 console.logs with newer timestamps

ComponentA hook observer 1665157525844
ComponentA hook observer 1665157525844
ComponentA hook observer 1665157525844

This will continue, every time I save ComponentA it seems to add another observer, which then gets triggered if I save somewhere else. Interestingly if I save ComponentA 10 times in a row before saving ComponentB, it only seems to add 1 more observer log.

Any idea what's happening?

App.tsx

import { enableLegendStateReact } from '@legendapp/state/react';
import React from 'react';
import ComponentA from './src/test/ComponentA';
import ComponentB from './src/test/ComponentB';

// Enable direct rendering of observables
enableLegendStateReact();

const App = () => {
  return (
    <>
      <ComponentA />
      <ComponentB />
    </>
  );
};

export default App;

ComponentA.tsx

import state from '../state';

const ComponentA = () => {
  useObserve(() => {
    console.log('ComponentA hook observer', state.settings.test.get());
  });
  return null;
};

export default ComponentA;

ComponentB.tsx

import {useEffect} from 'react';
import state from '../state';

const ComponentB = () => {
  useEffect(() => {
    state.settings.test.set(Date.now().toString());
  }, []);
  return null;
};

export default ComponentB;

state.ts

import settings from '../state/settings';
export default {settings, sites};

settings.ts

const settings = observable({
  test: undefined as string,
});

export default settings;

React Native - auth and guest stacks

so on most of my react-native projects i use react-navigation and there is a need for 2 stacks that conditionally render based on the user being authenticated or not. the way i currently achieved this by doing:

const app = useSelector(() => ({
  initialized: store.app.initialized.get(),
  isInternetReachable: store.app.isInternetReachable.get(),
  isAuthenticated: store.isAuthenticated.get(),
}));

<NavigationContainer>
  <Stack.Navigator>
    {!app.initialized ? (
      <Stack.Screen
        name="Initial"
        component={InitialScreen}
      />
    ) : !app.isAuthenticated ? (
      <Stack.Screen
        name="SignIn"
        component={SignInScreen}
      />
    ) : (
      <>
        <Stack.Screen
          name="Home"
          component={HomeScreen}
        />
      </>
    )}
   </Stack.Navigator>
</NavigationContainer>

is there a better / recommended way of doing this?

Accessing value before set gives the set value

Hey! I caught the stream with Jamon and wanted to take a look out of interest as I was keen to see how adding the run time type checking with zod via a plugin of some kind might go πŸ‘€

I wasn't sure if I've missed something in the docs, but if you see the below, I tried logging out the value prior to setting and it seems to give me the set value?

** Note ** - it gives the correct value if I call console.log("beforeSet", user.get());

https://codesandbox.io/s/mystifying-darkness-byq4gx?file=/src/App.tsx:0-848

image

import "./styles.css";
import { observable } from "@legendapp/state";
import { enableLegendStateReact } from "@legendapp/state/react";
import { z } from "zod";
enableLegendStateReact()
// const __DEV__ = true;
const User = z.object({
  name: z.string().nullable()
});
type zUser = z.infer<typeof User>;

const user = observable<zUser>({
  name: null
});

export default function App() {
  const onPress = () => {
    console.log("beforeSet", user);
    user.set({name: "my new name"});
  };
  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
      <button onClick={onPress}>Update that username!</button>
      <p>username: {user.name}</p>
    </div>
  );
}

Inserting elements in the middle of an array doesn't work

Using for example splice to insert an element in the middle of an array cases its and consecutive bindings to break/refer to the wrong element.

Sandbox:
https://codesandbox.io/s/legend-w-observable-forked-5s88ge?file=/src/App.tsx

Click the plus 3-4 times. Each time a new item gets inserted in the middle with a label of the total count.
Expected output after four clicks:

  • item 1
  • item 3
  • item 4
  • item 2

Actual output:

  • item 1
  • item 2
  • item 2
  • item 2

Now press the rerender button to see the JSON output the actual value (which has updated correctly)

Usage with State Machines

I'm an avid user of xstate and I'm curious if there are any thoughts on how to integrate this with state machines? would you need to wrap observable values in a state machine and produce them as part of the machine or is there a cleaner way to approach integrating the two?

Combined, they seem like they could be very powerful (xstate drives the state change and invocation of actions, and legend-state records and propagates the changes, if you will)

I'd love to explore this area!

Document reliance on internals

This library appears to significantly depend on React internals which aren't bound by semver.

I think it would be fair to add a notice that by taking it on as a dependency, you're making every React upgrade risky, and at some point might not be able to upgrade at all.

traceUpdates sometimes throws error on getPrevious

Just posting this issue publicly in case anyone runs into it. I will look into it soon.

Using traceUpdates in combination with computed is throwing errors. It's a pretty deep issue, incompatibility with the new enabledLegendReact() so it will take a little bit to rethink how tracing should work and fix it up.

Docs: Clarify import paths

Expected Behavior

Implementing example from the documentation should run.

Actual Behavior

Snack: https://snack.expo.dev/@danstepanov/legend-state

Worth noting that this neither works in Expo Snack nor via Expo Go.

IMG_0DB66D0BDEFD-1

Error: "(0 , _state.useObservable) is not a function" in TypeError: (0 , _state.useObservable) is not a function <<     at App (App.js.js:9:33 <<  <<     at co ([snack internals]

state not updating immediately

Hey Jay! Just discovered the library and tried to give it a spin by creating a simple todo list example, but I couldn't quite get it working. Here's the example:

https://stackblitz.com/edit/vitejs-vite-duyj73

Specifically, there's these issues:

  1. When I add the first todo it only appears after I add a second one
  2. Similarly the "done" toggle only renders after I click on it a few times
  3. Whenever the file gets hot-reloaded, the example stops working completely

Am I missing anything or is this a bug? Using 0.11.0-beta.2 btw.

ObservablePrimitive as a react component prop

I have this simple Input from chakra, essentially a regular html input.
See the typescript problem.

image

I tried to do this:

defaultValue={value as unknown as string}

but still get this error in the console

image

Running simple vite react project.

I am trying this project because of the hope that It could render components only once, similar to Solid.

React test is failing

Just a quick note, you may have already noticed this: one test in react.test.ts is failing.

Firebase & Firestore Plugins

Hello πŸ‘‹

A508CD9A-B807-406D-98F2-07A9A8C5171C

Just read this and would appreciate to know how far along the Firebase/Firestore plugins are.

Can you shed light on how it will work and if it will support both Firebase JS SDK on web (v8 and/or v9) and react-native-firebase on the native side?

Keep up the good work, you’re legends 😁

How to debounce

How to debounce without rerendering the component?
This does not work, 'debounceLodash' printed only once, though value is changing:

	const value = useObservable(props.defaultValue ?? '')
	const ref = useRef(
		debounceLodash(() => {
			console.log('debounceLodash')
			props.onChange(value.get())
		}, 200)
	)
	useObserve(ref.current)

React Native components throwing error

Legend State Version: 0.19.7

When trying to use the react native components from @legendapp/state/react-native-components, I get the following error:

Screen Shot 2022-10-11 at 9 44 12 PM

This is the code that caused it. I noticed that the react (web) components entry exports a legend object with components that have reactive props, while the react native entry exports Legend with components without reactive props. I also can't pass in observables to bindable views like TextInput without a typescript and runtime error. Do these components need to be updated to reflect the recent api changes, or am i missing a step to get them working?

import { View } from "react-native";
import { observer, useObservable } from "@legendapp/state/react";
import { Legend } from "@legendapp/state/react-native-components";

export default observer(function App() {
  const text = useObservable("Hello World");
  return (
    <View>
      <Legend.Button title="hi" />
      <Legend.TextInput value={text} />
    </View>
  );
});

useComputed doesn't update on deps change

We have our own mobx-based useComputed, and I was looking at Legend's implementation just out of curiosity.

I thought this approach was neat:

                // setValue may be undefined if this is the first run
                setValue?.(v);

But in trying the approach out for our useComputed test suite, it doesn't actually work b/c contrary to the comment of "setValue is only undefined on the first run", it's actually always undefined, b/c on the 2nd run, i.e. useMemo has noticed that deps has changed and running effect again (for us autorun), setValue is still undefined, b/c this is a brand new invocation of the useComputed function, and setValue-the-setter still hasn't been set by useState.

I think for this to work you'd need to use a ref to hold the setValue? i.e. something like:

function useComputed(...) {
  const setValueRef = useRef();
  const initial = useMemo(() => {
    ...
    if (setValueRef.current) setValueRef.current(v);
  });
  const [value, setValue] = useState(initial);
  // Let the next invocation of useComputed get setValue
  setValueRef.current = setValue
  return value;

Docs: Removing property from observable with delete()

I try to create an observable state with dynamic properties.
Adding an new property to the observable works like a charm but removing is not possible.
Is there a way to remove properties from an observable after it was set?

React Native Switch component how to update state?

I've tried a couple variations and can't figure out how to make the switch component react to the toggle event. I assumed like input it would update on its own and update the observable, but it doesn't seem to work that way.

Here's what I've tried:

import * as React from 'react'
import { useObservable } from '@legendapp/state/react'
import { Legend } from '@legendapp/state/react-native-components'

export const Component = () => {
  const isSelected = useObservable(true)

  isSelected.onChange(value => {
    console.log(value) // `undefined`
  })

  const handleValueChange = value => {
    // value = `undefined`
    console.log(isSelected.get()) // `undefined`
    isSelected.set(!isSelected.get())
  }

  return (
        <Legend.Switch value$={isSelected} onValueChange$={handleValueChange} style$={Styled.switchStyle} />
  )
}

I'm not sure how to update the state, or listen and react to state updates.
I've also tried not setting the value in handleValueChange which also doesn't update the state, but when I do update the state in handleValueChange I get the following error:

Error

Doesn't work on mobile web

Thanks guys for including this somewhere as I just found out after swapping nearly everything to legend state it just doesn't work on mobile brilliant 12/10. πŸ‘πŸ»

Improve typing of `item` in `For` component

I'm not quite sure why, but the TypeScript typing of the item argument inside the For component seems to not recognise the type of the list as provided to the each argument.

Screenshot taken from my example:

Screenshot 2022-10-17 at 12 23 35

enableLegendStateReact is amazing

I was just checking in on legend-state, and saw the new observer-less/useComputed-less React integration. Like, lol, wat? That's super neat.

My understanding is that, by hooking into this setter, you're basically getting react to give you a "beginRender" and "endRender" API, which lets you wrap every React component with the equivalent of the observer HOC behavior.

Does that sound right?

If so, I wonder if a small TLDR of that might be useful in the docs and/or source, just as a hint to others who will wonder the same "wtf does this even work?" and potentially not trust it until they understand (e.g. I thought maybe it'd require the babel plugin or something like that).

I have conflicting emotions; this is even more amazing to get SolidJS-style brevity/reactivity in React, but I don't know I'd bet/couple a large codebase to something that might break in React 19/20/etc. I suppose the worst case scenario would be to go back and add observer HOCs to components. That wouldn't be terrible.

I wonder if the React team would be open to this sort of beginRender / endRender API. Or almost like render middleware. I imagine surely they've been asked this before, multiple times, and said no, so 🀷 .

But anyway, this is not an issue, just wanted to call out how amazing this is. Great work!

useObservable does not work with prefilled arrays.

Following does not work:

// contents of data
const data = [{id: 'Test1', data: 'test1'}];


const Test = ({data}) => {
    const arr = useObservable(data);

   const handleClick = () => {
       arr.push({id: 'Test', data: 'test'});
   };

   return (
       <>
           <button onClick={handleClick}>add</button>
           <pre>{JSON.stringify(arr.get(), null, 4)}</pre>
       </>
   );
}

an click on the button gives this error:

"Uncaught TypeError: Cannot read properties of undefined (reading 'get')
at updateNodes (index.mjs?8ffd:528:1)
at setKey (index.mjs?8ffd:819:1)
at set (index.mjs?8ffd:756:1)
at Proxy.eval (index.mjs?8ffd:655:1)
at eval (index.tsx?83a8:42:22)
at commitHookEffectListMount (react-dom.development.js?ac89:23150:1)
at commitPassiveMountOnFiber (react-dom.development.js?ac89:24926:1)
at commitPassiveMountEffects_complete (react-dom.development.js?ac89:24891:1)
at commitPassiveMountEffects_begin (react-dom.development.js?ac89:24878:1)
at commitPassiveMountEffects (react-dom.development.js?ac89:24866:1)
at flushPassiveEffectsImpl (react-dom.development.js?ac89:27039:1)
at flushPassiveEffects (react-dom.development.js?ac89:26984:1)
at commitRootImpl (react-dom.development.js?ac89:26935:1)
at commitRoot (react-dom.development.js?ac89:26682:1)
at performSyncWorkOnRoot (react-dom.development.js?ac89:26117:1)
at flushSyncCallbacks (react-dom.development.js?ac89:12042:1)
at flushSync (react-dom.development.js?ac89:26201:1)
at scheduleRefresh (react-dom.development.js?ac89:27795:1)
at renderer.scheduleRefresh (react_devtools_backend.js:6514:16)
at eval (react-refresh-runtime.development.js?7e84:265:1)
at Set.forEach ()
at Object.performReactRefresh (react-refresh-runtime.development.js?7e84:254:1)
at eval (helpers.js?403c:124:1)"

if i use it like this everything works:

const Test = ({data}) => {
    const arr = useObservable([]);
   
   arr.set(data);

   const handleClick = () => {
       arr.push({id: 'Test', data: 'test'});
   };

   return (
       <>
           <button onClick={handleClick}>add</button>
           <pre>{JSON.stringify(arr.get(), null, 4)}</pre>
       </>
   );
}

`For` is not compatible with TypeScript

Hi @jmeistrich, I try to use the array with For but it does not work.

const a = observable<{ id: string; name: string }[]>([])

const k = (
  <For each={a}>
    {(item) => (
      <div>{item.name}</div>
    )}
  </For>
)

I get this error

Property 'name' does not exist on type 'ObservableObject<{ id: string | number; }> | ObservableObject<{ _id: string | number; }> | ObservableObject<{ __id: string | number; }>'.
  Property 'name' does not exist on type 'ObservableObject<{ id: string | number; }>'

I try to cast the item variable with ObservableObject<{ id: string; name: string }> and get this:

Type '(item: ObservableObject<{    id: string;    name: string;}>) => JSX.Element' is not assignable to type '(value: ObservableObject<{ id: string | number; }> | ObservableObject<{ _id: string | number; }> | ObservableObject<{ __id: string | number; }>) => ReactElement<...>'.
  Types of parameters 'item' and 'value' are incompatible.
    Type 'ObservableObject<{ id: string | number; }> | ObservableObject<{ _id: string | number; }> | ObservableObject<{ __id: string | number; }>' is not assignable to type 'ObservableObject<{ id: string; name: string; }>'.
      Type 'ObservableObject<{ id: string | number; }>' is not assignable to type 'ObservableObject<{ id: string; name: string; }>'.
        Property 'name' is missing in type 'ObservableFnsRecursiveSafe<NonPrimitiveKeys<{ id: string | number; }>> & ObservableFnsRecursiveUnsafe<PrimitiveKeys<{ id: string | number; }>> & ObservableObjectFns<...>' but required in type 'ObservableFnsRecursiveUnsafe<PrimitiveKeys<{ id: string; name: string; }>>'.ts

RN cycle dependencies warning

In react-native project, that uses pnpm(not sure whether it's pnpm-specific), i've got such a warning:

 WARN  Require cycle: ../../node_modules/.pnpm/@[email protected]/node_modules/@legendapp/state/react.js ->
../../node_modules/.pnpm/@[email protected]/node_modules/@legendapp/state/react.js

This is not critical, but it would be nice to remove this for more comfortable RN use.

Docs: Add note about non-keyed benchmark

Hi,

I was intrigued by the performance claims of this library and realised that you aren't comparing apples to apples with the 'optimized' krausest benchmark, seen here:

image

It appears to me that you are comparing a non-keyed implementation of the benchmark (the optimized bench re-uses nodes) to keyed implementations.

I suggest that you add a note to the following page that the optimised benchmark is not keyed, so as to not mislead.
https://legendapp.com/open-source/state/fast/

Thanks

For Typing

The item is mistyped.

export const state = observable({
	items: [
		{ id: '0', top: 100, left: 100 },
		{ id: '1', top: 150, left: 100 },
		{ id: '2', top: 200, left: 100 },
	],
})

const Board = () => {
	return (
		<Box>
			<For each={state.items}>{(item) => <div />}</For>
		</Box>
	)
}

Sometimes `when` is not triggered

Sometimes, when I try to navigate between my routes, the state changes but the when function is not triggered. I am using react-location (Data API). Now I have to switch to authorization.state.onChange

when(
  () => authorization.state.get() === 'unauthorized',
  () => {
    import('@/utils/modal').then(({ showLoginModal }) => {
      showLoginModal()
    })
  }
)

when(
  () => authorization.state.get() === 'anonymous',
  () => {
    console.log('logout')
    if (history.location.pathname.includes('/dashboard')) {
      history.push(
        {
          pathname: '/login',
          search: `?redirect=${encodeURIComponent(
            `${history.location.pathname}${history.location.search}`
          )}`,
        },
        history.location.state
      )
    }
  }
)

Improve documentation and examples for Array

As a beginner with this library, I find it quite complicated and confusing when to use the Observable (Proxy?) and when to use the actual data one would get by calling .get() or .peek() on the Observable.

The page in question: https://www.legendapp.com/open-source/state/arrays/

For example, when I use .splice() as mentioned in the documentation, it's not clear which one to use:

obs.arr.splice()
obs.arr.get().splice() // and then call .set()

In my Sandbox example I figured, I would have to .get() the actual Array, modify it and then .set() the new Array, otherwise I would just run into errors.

I think it would be useful for new users to clarify usage, especially since splice is mentioned on the page, but not used or explained further.

I think the first example listing on the page (regarding the For component) has a mistake, as it uses variable list for the each property, which is not defined anywhere. It would be clearer if you'd replace each={list} with each={obs.arr}.

Handle putting JSX elements into observables

Hey! Been doing some exploring into legend and we're super excited about it!

During our initial exploration I wanted to try and convert our dialog system to use Legend since it's pretty straightforward and ran into some issues (probably due to my misunderstanding of how legend works).

I tried two approaches, the first works great but I was curious if there's a way to get approach #2 to work since it's similar to how our team has used observables in React w/ our hand-rolled solution in the past.

Approach #1 - Working
Using observable
Here's a link to the sandbox: https://codesandbox.io/s/legend-w-observable-osyjnj

Was able to import the dialogObs created through the observable fn and access the observable directly inside any child components, didn't run into any issues w/ this.

Approach #2 - Borked
Using useObservable

Link to the sandbox: https://codesandbox.io/s/legend-useobservable-uwj1cu?file=/src/App.tsx:85-98

Wanted to see if we could pass down the dialogObs directly through a line of child components via props and it's throwing a TypeError:

'getOwnPropertyDescriptor' on proxy: trap reported non-configurability for property '$$typeof' which is either non-existent or configurable in the proxy target

Is there an issue w/ the way I'm trying to use useObservable or is there something else going on?

Add index to function in `For` component

I'd find it convenient if the For component would expose an item index, similar to what Array.map, Array.forEach, etc. do in JavaScript. I don't know if there is a reason for not having it.

In my Sandbox example I use useSelector() to build a Map to map the IDs of Array objects to their current index numbers. This seems overly complicated.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.