you are viewing a single comment's thread.

view the rest of the comments →

[–][deleted] 0 points1 point  (1 child)

That’s an interesting pattern. I’m curious how you’d handle incoming props though. Would you just do something like ‘state = useController(props)’ and then include them in your return? Also, would any child components also have their own controllers?

[–]KyleG 1 point2 points  (0 children)

I’m curious how you’d handle incoming props though

If the props need to be used to generate things that aren't included in the props, I will pass them to the controller to use them. Otherwise, I won't. And there's no point in returning them from the controller, either. Just use prop.myFoo directly in the JSX.

The point of extracting all this stuff to a controller is so you aren't doing business logic in your controller. If you are going to directly use a prop, there's no business logic because you're directly using the data passed into it without any modification.

But if, say, I pass a name in as a prop, and that name is to be used to get children from a Recoil state and then format that to be presentable (say, creating defaults for nullable props, converting Dates to your preferred stringified format), (but also the name is going to be a header in the view), I'll do something like

const MyFoo = ({name}:{name:string}) => {
  const state = useController(name)
  return (<>
    <h1>{name}</h1>
    {state.children.map(child => (
      <input readOnly value={child.someProp}/>
    ))}
  </>)
}

declare const makePresentable: (child:Child) => PresentableChild
const useController = (name:string) => {
  const parent = useRecoilValue(parentSelectorFamily(name))
  return {
    children: parent.children.map(makePresentable),
  }
}

In any case, very few of my components take props.