Search code examples
javascriptreactjsrecompose

Recompose async prop update


How to rerender component with recompose, when prop is changed from outside the view component?

const Message = ({msg}) => <div>The prop has a value of <b>{msg}</b>.</div>

const App = Recompose.withProps(() => {
  let msg = 'One'

  // this async update doesn't work because nothing triggers a rerender
  setTimeout(() => {msg = 'Two'}, 500)

  return {msg}
})(Message)


ReactDOM.render(<App/>, document.getElementById('app'))

When this component is rendered, it shows value as One but doesn't change to Two after 500ms even though it changes the prop.

The setTimeout here simplifies the case when in the actual usecase I subscribe to websocket server and when a message is pushed, the Message component gets updated.


Solution

  • Disclaimer: I did not work with recompose actively yet.

    But what I know is that your component should be stateful. I found withState in recompose docs

    const enhance = withState('counter', 'setCounter', 0)
    const Counter = enhance(({ counter, setCounter }) =>
      <div>
        Count: {counter}
        <button onClick={() => setCounter(n => n + 1)}>Increment</button>
        <button onClick={() => setCounter(n => n - 1)}>Decrement</button>
      </div>
    )
    

    So what I think is, you need to define the state msg using withState and then you can pass the setMsg into your component. when calling this setMsg within your setTimeout an update should be performed.

    const withMsg = withState('msg', 'setMessage', '');