使用重组,如何使用常规道具覆盖状态中的映射道具?
using recompose, how overwrite mapped prop from state, with regular prop?
构建简单的 phone 输入表单组件:
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>
)
}
}
当用户在字段中键入 phone 时,此函数会更新 errorText
属性:
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)
};
此代码增强了组件,您可以看到 errorText
prop 也来自 redux 状态:
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
}),
)
当用户单击按钮并且网络请求失败时,我从 reducer 收到错误,然后将其作为 errorText
道具映射到组件。但是当用户再次编辑 phone 时,应该会出现 "Please enter valid number" 错误,但是来自 redux 的 prop 仍然存在,而我的 changePhoneInput
没有更新 prop。如何避免这种情况?
我尝试在 compose 中更改函数的位置,但没有帮助。我基本上需要的是用 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
,它可以将withState
和withHandlers
合并为一个HOC。
构建简单的 phone 输入表单组件:
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>
)
}
}
当用户在字段中键入 phone 时,此函数会更新 errorText
属性:
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)
};
此代码增强了组件,您可以看到 errorText
prop 也来自 redux 状态:
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
}),
)
当用户单击按钮并且网络请求失败时,我从 reducer 收到错误,然后将其作为 errorText
道具映射到组件。但是当用户再次编辑 phone 时,应该会出现 "Please enter valid number" 错误,但是来自 redux 的 prop 仍然存在,而我的 changePhoneInput
没有更新 prop。如何避免这种情况?
我尝试在 compose 中更改函数的位置,但没有帮助。我基本上需要的是用 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
,它可以将withState
和withHandlers
合并为一个HOC。