0

Building simple phone input form component:

class PhoneSettingsScreen extends React.Component {
    render() {
        const {changePhoneInput, submitPhone, errorText, loading} = this.props
            return (
                <View>
                    <TextInput onChangeText={changePhoneInput}/>
                        <Text style={{color: 'red'}}>{errorText}</Text>
                        <Button
                            onPress={submitPhone}
                        />
                        {loading && <Spinner/>}
                    </View>
                </View>
            )
        }
    }

when user types the phone in field, this function updates errorText prop:

const changePhoneInput = props => phone => {
    const {setPhone, setErrorText} = props
    setPhone(phone)
    let error = /[0-9]{6,9}/g.test(phone) ? '' : "Please enter valid number";
    setErrorText(error)
};

component is enhanced with this code, and you can see errorText prop is coming from redux state as well:

const enhance = compose(
    withState('errorText', 'setErrorText', ''),
    connect((state, nextOwnProps) => {
        state = state.get('settings')
        return {
            loading: state.get('loading'),
            errorText: state.get('error')
        }
    }, {
        submitPhoneAction
    }),
    withState('phone', 'setPhone', ''),
    withHandlers({
        changePhoneInput,
        submitPhone
    }),
)

When user clicks button, and network request failed, from reducer I receive error which I map then to a component as an errorText prop. But when user edits phone again, "Please enter valid number" error should show up, but prop from redux remains, and my changePhoneInput doesnt update the prop. How to avoid this ?

I tried to change positions of functions in compose, it didn't helped. what I basically need is to overwrite errorText prop in my component with changePhoneInput function. Of course I can use another variable name but I think there should be another way to solve this issue.

Ilja
  • 1,205
  • 1
  • 16
  • 33

1 Answers1

0

You can override the store state in connect

const enhance = compose(
    withState('errorText', 'setErrorText', ''),
    connect((state, nextOwnProps) => {
        state = state.get('settings')
        return {
            loading: state.get('loading'),

            // You can override the store state here, ex:
            errorText: nextOwnProps.errorText || state.get('error')

        }
    }, {
        submitPhoneAction
    }),
    withState('phone', 'setPhone', ''),
    withHandlers({
        changePhoneInput,
        submitPhone
    }),
)

However, I recommend you to take a look at withStateHandlers, which can combine withState and withHandlers into one HOC.

wuct
  • 10,057
  • 2
  • 19
  • 22