Hacker News new | past | comments | ask | show | jobs | submit | tannerlinsley's comments login


Keyword clustering that finds the overlapping URLs in the top 10 between SERPs to generate clusters with actionable metrics like Traffic Opportunity, Max Estimated Traffic, and more. You can start improving your content and SEO based on real data.


You have no idea how excited I am about this.


TLDR: I write and maintain several good-sized typescript libraries so I write library types all the time. In fact, I'm writing them right now! TypeScript is what makes them really fun to use. They infer everything they can and have very high levels of safety and passthrough while still allowing for composition and extension at the framework-adapter and library level. I will never consider writing another OSS tool in the JS ecosystem without ensuring the typescript experience is the best I can offer.

That said...

I've learned that "library" types might not be the best way to talk about these concepts. What we're really talking about here are types that are complex/advanced enough to force you to venture beyond the primitive building blocs in the TS docs and into existing open source solutions that have trail-blazed more advanced use-cases. It took me only a few weeks to get comfortable with common TS, but at least a year to feel dangerous enough to write more advanced TS. I'm on year 3 now and I am still learning/forgetting so much about it.

I agree that: - Advanced types and their concepts are difficult to learn. - There is limited documentation on how to create/use them. - They can sometimes be difficult to reason about, mainly due to the limited syntax TS offers around advanced concepts.

On the the positive: - They can be learned with practice. - There is plenty of OSS out there to learn from - Once you learn them, you start to think differently about TS as a language instead of annotations

I wish there were better features/syntax support for: - Optional generics - Higher-order generics / Polymorphic generics (basically higher-order functions, but for types) - More built-ins (like ts-toolbelt, type-fest, etc)

I think this ramp of difficulty with advanced TS types is fine for the most part. Library authors have always carried way more of a burden than devs at the edge, even during runtime to ensure things like size, performance, flexibility, etc. TS is just another facet that is becoming more an expectation every day.

At the end of the day, a library dev gets to choose what level of investment they'll put into great types for their library. If they can pull it off, their tool will likely provide a measurably better developer experience.

That's my goal for my libraries, so choosing to go all-in on advanced TS is now a no-brainer.

Anywho, good luck!


Thanks!



Agreed. Most if not all of the production tables I have are using very simple architecture. Pagination + Data Exploration utilities like sort/filter/group/etc.

In no way am I preaching that these plugins should used. However, I am proud that they can be used. And if you end up being one of the users that only needs a few things to make your production tables great, then you win again by being able to treeshake out all of the other stuff you choose not to use.


I would love to hear how you would solve these problems yourself. Any ideas are very appreciated. Still, the patterns and tradeoffs built into React Table are not fleeting exploratory concepts that we hope will catch on, they are architected this way for a purpose. Sure, it doesn't come with any opinionated UI, but in the future, opinionated UIs for React Table will likely exist (some are already in development by 3rd parties). Until then, there are plenty of examples that show you just how easy it is to implement things like virtualization. Having control of the markup for a data grid can be intense and intimidating for those who aren't use to building their own tables, but again, once you see how little work there is to do in your own components, you'll see the power in the library (like having full control over styles, building your own UI APIs, prop patterns, state management paradigms, etc.) As for the prop spreading............... It's fantastic and I would love to see anyone convince me of a more elegant/composable pattern for decorating arbitrary and unknown markup.


You can control the table from wherever you can put the `useTable` hook. 99% of the time this will be in your table component, but nothing is stopping you from hoisting this higher or decorating it with whatever other logic you want. Even if you chose not to hoist the hook, there is also nothing stopping you from listening to props and using callbacks to update this state. This is not a constraint of the API and more a constraint of how you choose to model your component-hook composition points.


Tell me if I'm wrong, but skimming the docs I understand that the table's filter state is in the local state of the table (state defined in the hook).

If it's the case, it does mean that the table component isn't controlled (as in "controlled input component"). What you describe (if I understand correctly) is _synchronising_ the local state of the table with my own global state, instead of controlling the table (giving my global state as param of the hook). This is breaking the one-way data flow that makes React so good.

The API I would expect would look more like:

    useTable(
        useFilter({value: myValue, onChange: myHandler})
    )

But I might be misunderstanding something, in which case please correct me! I am very interested in your library, the pattern has been around for a while but tables in React are always a PITA as they combine the problems of forms + lists + crazy interactivity


It's one-way control. There is no reasonable way to implement narrative "now my filter resides in global state. Whenever component changes, it's reflected in the state. Whenever state changes it's reflected in component". I asked this question in spectrum community https://spectrum.chat/react-table/general/how-to-control-fil...


There's definitely a difference between taking table state and storing it somewhere globally for use later and 100% controlling the table state from outside of the table. Doing the latter involves listening to the table state for changes in an effect, shipping the new state up to your higher-than-component storage location, detecting in that same component a change in the global storage location (usually just a memoized prop or hook of sorts) and updating the table state with your updated global state using either a table method like instance.setFilter or even a state reducer if you want total control. The tools are in place and the API is flexible enough to do what you are referring to. I'm sorry your comment in Spectrum got lost in the noise and that you had to resort to posting your question on here.


Thanks for detailed explanation and your time. I do understand that things I want to achieve are achievable. But I'm not happy with the complexity price I have to pay.

I believe that moving in the implementation between local and global state should be a snap. It's a matter of time when need to move local state to global will arise. And hooks have nothing to propose for that.

Good luck with your project.


There's nothing wrong with having useStore() next to useTable() and using a few effects to keep them in sync.


This would be acceptableway to go. But I did not manage to get it working. Saw your comment how to fix, but don't have code to validate that everything would work as expected.

Thanks.


FWIW that code snippet is broken -- you need to memorize your effect with [store.filter] to avoid the infinite loop.


It's a codesandbox bug. Log in with github for now to bypass the error.


The first thing I looked for was screenshots in the readme. But one has to go look for it many clicks deep and launch a 3rd party editor (which can be buggy), and let whatever engine parse and run the code to render the whole thing, just to see what it looks like.

You have a huge colorful banner at the top of the readme, why not screenshots?


Being a headless table utility, any screenshot of the table UI would either be over or under selling the potential UI that users will implement with the library. If you noticed the exmamples are very bare bones styles so as to highlight the functionality of the library. These examples would be "ugly" as marketing material. If another example was super dressed up and looked amazing and used as marketing material, users may be disappointed when they realize they are in charge of their own styles. It's 6's I believe, so I went with what I thought was the safest option, exclusion of screenshots.


I suppose then, a screenshot of source code next to the rendered output is what programmers desire, in the introduction. Instead of thinking "That's a sexy table!", the programmers will hopefully think "That's some sexy table-generating code!".


Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: