builder: React: doesn't rerender when user attributes change

We have a basic Builder component:

<BuilderComponent model="home-pages" />

If we call builder.setUserAttributes before this renders, it will pass the correct attributes to the Builder API and render the correct content.

If we then call builder.setUserAttributes after this renders (e.g. if the user signs in), it doesn’t show the new content.

Problem 1: Builder doesn’t fetch new content from the API. We can tell this is a problem because there’s nothing in the network tab when we call builder.setUserAttributes.

Problem 2: Builder fetches new content from the API, but the component doesn’t update. We can tell this is a problem because even if we manually fetch new content and pass it into <BuilderComponent>, it doesn’t update:

// doesn't work:
function MyComponent() {
  const [content, setContent] = useState(null)

  useEffect(() => {
    builder.get('home-pages').promise().then(setContent)
  })

  return <BuilderContent model="home-pages" content={content} />
}

// works:
function MyComponentWithKeyUpdate() {
  const [content, setContent] = useState(null)

  useEffect(() => {
    builder.get('home-pages').promise().then(setContent)
  })

  return <BuilderComponent model="home-pages" content={content} key={content.id} />
}

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 17 (13 by maintainers)

Most upvoted comments

btw we found a bug that with the last release with symbols not displaying in the editor, so when you upgrade I’d recommend using @builder.io/react@1.1.17 😃

will also release again if needed when we find what might be causing unsubscribing to not always work

Yeah @antonhalim it follows the ES Observable spec so you just do

const subscription = builder.userAttributesChanged.subscribe(incrementUserAttributesVersion)

// when you need to unsubscribe
subscribption.unsubscribe()

With the observer, we can at least wrap <BuilderComponent> with our own version that does update automatically:

export default function MyBuilderComponent(props) {
  const [userAttributesVersion, setUserAttributesVersion] = useState(0)

  useEffect(() => {
    function incrementUserAttributesVersion() {
      setUserAttributesVersion(userAttributesVersion + 1)
    }

    builder.userAttributesChanged.subscribe(incrementUserAttributesVersion)

    return () => { builder.userAttributesChanged.unsubscribe(incrementUserAttributesVersion) })
  })

  return <BuilderComponent {...props} key={userAttributesVersion} />
}

Nice, thanks!

this is now officially released with @builder.io/react@1.1.16

Thanks for the thorough ticket @jamesarosen

Just published @builder.io/react@1.1.16-alpha.10 that adds an observable for listening to user attributes changing as:

builder.userAttributesChanged.subscribe(handler)

As well as properly handling new content being passed in

If you run into any further issues with this version or newer just let us know!