Perspective
Perspective

Reputation: 632

React Recompose Initial state value form Async Source

In the following example in recompose, withState has an initial value of empty string. What if you needed a value form a database or dynamic source, how would you have it update on that prop change?

For example:

withState('value', 'updateValue', (user) => user.name)

Original code from recompose;

const enhance = compose(
  withState('value', 'updateValue', ''),
  withHandlers({
    onChange: props => event => {
      props.updateValue(event.target.value)
    },
    onSubmit: props => event => {
      event.preventDefault()
      submitForm(props.value)
    }
  })
)

const Form = enhance(({ value, onChange, onSubmit }) =>
  <form onSubmit={onSubmit}>
    <label>Value
      <input type="text" value={value} onChange={onChange} />
    </label>
  </form>
)

Upvotes: 0

Views: 1673

Answers (2)

Isaddo
Isaddo

Reputation: 438

You can get the value asynchronously below the state, and then call the updater. React Docs suggest to do these things in componentDidMount

const enhancer = compose(
  withState('value', 'updateValue', ({ name }) => name),
  withHandlers({
    onChange: props => event => {
      props.updateValue(event.target.value)
    },
    onSubmit: props => event => {
      event.preventDefault()
      submitForm(props.value)
    }
  }),
  lifecycle({
    componentDidMount () {
      fetchName().then(this.props.updateValue)
    }
  }),
  branch(({ name }) => !name, () => null)
)

Upvotes: 1

Perspective
Perspective

Reputation: 632

Given the example above, I just branched;

v4 I just seem to have race conditions so I made sure that these specific components wouldn't render until it's considered done loading. Now I can go back to the original code;

v3 The following works, and perhaps their is a better way or tools I could be using within recompose.

withState('value', 'updateValue', ''),
withPropsOnChange(['name'], (props) => assign(props, { value: props.name })),

v2 By removing branch and adding withPropsOnChange I was able to achieve what I wanted. (or so it seemed)

withPropsOnChange(['name'], ({ name }) => ({ name })),
withState('nameValue', 'updateNameValue', ({ name }) => name ),

v1 First Attempt: (Did not work out too well)

const enhance = compose(
  branch(
    ({ name }) => !name,
    renderNothing
  )
  withState('value', 'updateValue', ({ name }) => name),
  withHandlers({
    onChange: props => event => {
      props.updateValue(event.target.value)
    },
    onSubmit: props => event => {
      event.preventDefault()
      submitForm(props.value)
    }
  })
)

const Form = enhance(({ value, onChange, onSubmit }) =>
  <form onSubmit={onSubmit}>
    <label>Value
      <input type="text" value={value} onChange={onChange} />
    </label>
  </form>
)

Upvotes: 1

Related Questions