我很反应原生和异步编程,并试图理解如何“同步”redux状态值和本地状态值。
例如,我有一个文本字段“aboutMe”存储服务器端,并使用mapStateToProps将其放入道具:
const mapStateToProps = (state) => {
return { aboutMe: state.aboutMe };
}
在渲染中,我有一个TextInput我正在使用,以便用户可以编辑这个字段,我想默认为服务器端保存的内容:
<TextInput
onChangeText={(aboutMe) => {
this.setState({aboutMe});
}}
value={this.state.aboutMe}
/>
基本上,我需要打电话
this.setState({ aboutMe: this.props.aboutMe });
哪里适合这个地方?我试图使用componentWillReceiveProps,但是生命周期方法没有在构造函数上调用,所以我需要setState两次(在构造函数和componentWillReceiveProps中)。
还有其他办法吗?我觉得这是一个非常普遍的问题,许多反应原生开发人员已经解决了,但我找不到一种普遍接受的在线方式。
谢谢!
编辑:
我有很多TextInputs,所以我有一个单独的按钮来调用保存变量的动作:
<Button onPress={()=>{
this.props.saveUserInput(this.state.aboutMe,
this.state.name, this.state.address, ....}}>
<Text> Save changes </Text>
</Button>
从评论中我了解到可以调用onChangeText上的保存操作......但来回的流量是否过多?将所有变量本地保存到状态然后立即调用一切保存会更好吗?此外,如果用户想要“取消”而不是保存,该怎么办?这些更改已经保存,我们将无法放弃更改?
答案 0 :(得分:3)
1)如果你的组件是受控组件(你需要状态)并且请求是异步的,你必须像componentWillReceiveProps
一样设置状态:
class ExampleComp extends Component {
constructor(props) {
super(props);
this.state = {
aboutMe: ""
}
}
componentWillReceiveProps(nextProps) {
this.setState({
aboutMe: nextProps.aboutMe,
});
}
render() {
return (
<TextInput
onChangeText={(aboutMe) => {
this.setState({aboutMe});
}}
value={this.state.aboutMe}
/>
);
}
}
请记住,这里的关键是,从现在开始,国家必须仍然是唯一的事实来源。
2)另一个选项是,您可以等到父组件中的请求完成,然后在构造函数中设置aboutMe
,这样就可以避免componentWillReceiveProps
。例如:
class ParentComp extends Component {
render() {
return (
<div>
{this.props.aboutMe && <ExampleComp/>}
</div>
);
}
}
class ExampleComp extends Component {
constructor(props) {
super(props);
this.state = {
aboutMe: props.aboutMe
}
}
render() {
return (
<TextInput
onChangeText={(aboutMe) => {
this.setState({aboutMe});
}}
value={this.state.aboutMe}
/>
);
}
}
这样做的缺点是在请求完成之前,文本输入不会显示。
答案 1 :(得分:1)
既然你已经编辑了你的问题,那么你想要实现的目标就更清楚了,所以我想解决这个问题。
您可以将受控输入元素的状态保留在组件中,然后使用redux存储来存储持久数据并填充默认值。
class Component extends React.Component {
constructor(props) {
super(props)
this.state = {
aboutMe: props.aboutMe,
... // other data
}
}
handleSubmit = (event) => {
event.preventDefault() // To prevent redirect
// Dispatch the save user input action
this.props.dispatch(saveUserInput(this.state))
}
render() {
return (
<form onSubmit={this.handleSubmit} />
<TextInput onTextChange={text => this.setState({...this.state, aboutMe: text}) />
... // input fields for other data
// Clicking this fill trigger the submit event for the form
<button type="submit">Save</button>
</form>
)
}
}