使用重构,如何使用常规 prop 从状态覆盖映射的 prop



构建简单的电话输入表单组件:

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>
            )
        }
    }

当用户在字段中键入电话时,此函数将更新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)
};

组件通过以下代码进行了增强,您可以看到 prop 也来自 Redux 状态errorText

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
    }),
)

当用户单击按钮并且网络请求失败时,我从化简器收到错误,然后将其映射到组件作为errorText道具。但是当用户再次编辑手机时,应该会出现"请输入有效号码"错误,但来自 redux 的道具仍然存在,并且我的changePhoneInput没有更新道具。如何避免这种情况?

我试图在组合中更改函数的位置,但没有帮助。 我基本上需要的是用changePhoneInput函数覆盖组件中的errorText道具。当然,我可以使用另一个变量名称,但我认为应该有另一种方法来解决此问题。

您可以在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
    }),
)

但是,我建议您查看 withStateHandlers ,它可以将withStatewithHandlers组合成一个 HOC。

最新更新