Javascript 当React Redux中的状态更改时,如何关闭模式对话框?
基本上,当Redux存储中的全局状态发生更改时,我希望更改组件中的UI状态 我的设想如下:Javascript 当React Redux中的状态更改时,如何关闭模式对话框?,javascript,reactjs,redux,react-redux,Javascript,Reactjs,Redux,React Redux,基本上,当Redux存储中的全局状态发生更改时,我希望更改组件中的UI状态 我的设想如下: 当用户单击“添加学生”按钮时显示模式窗体 当用户单击“保存”按钮时显示“保存…” 如果发生错误,对话框应保持打开状态并显示错误 如果插入正常,对话框应自动关闭 我已经获得了前3分,但我仍停留在第4点,不知道如何在成功插入后实现Close功能 每当在Redux存储中更改IssubMatting/error时,我都希望运行以下示例代码。但是,我不知道在哪里运行它。我试图将它放在render()方法中,但它不
Close
功能
每当在Redux存储中更改IssubMatting/error时,我都希望运行以下示例代码。但是,我不知道在哪里运行它。我试图将它放在render()方法中,但它不起作用,我无法再打开对话框
代码以检查并关闭模式
我不想将UI状态(例如IsModalOpen-bool)提升到全局Redux商店中。我已经将UI状态“isSubmitting”放入Redux,我不想继续将UI状态添加到Redux存储中
您能建议我如何在成功插入后关闭对话框吗
我把示例代码放在CodeSandbox上
减速器
const initialState = {
isSubmitting: false,
error: null,
student: null
};
function rootReducer(state = initialState, action) {
switch (action.type) {
case "STUDENT_ADD_BEGIN": {
return {
...state,
isSubmitting: true
};
}
case "STUDENT_ADD_SUCCESS": {
return {
...state,
student: action.payload,
error: null,
isSubmitting: false
};
}
case "STUDENT_ADD_ERROR": {
return {
...state,
isSubmitting: false,
error: action.error,
student: null
};
}
default:
return state;
}
}
export default rootReducer;
容器/页面
class addStudentPage extends Component {
constructor(props) {
super(props);
this.state = {
dataList: [],
add: false,
edit: false,
dataItem: {}
};
}
getInitialState() {
return {
id: "",
name: "TTCG"
};
}
componentDidMount() {
this.setState({
dataItem: this.getInitialState()
});
}
toggleAdd = () => {
this.setState(prevState => ({
add: !prevState.add
}));
};
showAddNew = () => {
this.toggleAdd();
this.setState({
dataItem: this.getInitialState()
});
};
updateItemState = event => {
const field = event.target.name;
const value = event.target.value;
let item = this.state.dataItem;
item[field] = value;
return this.setState({ dataItem: item });
};
handleAddNew = () => {
let item = this.state.dataItem;
item["id"] = uuid.v4();
console.info(item);
this.props.addStudentAction(item);
};
render() {
const { isSubmitting, error } = this.props;
return (
<Container>
<h1>Students</h1>
<Button onClick={this.showAddNew} color="link">
Add New Student
</Button>
{this.state.add && (
<AddStudent
toggle={this.toggleAdd}
modal={this.state.add}
item={this.state.dataItem}
onChange={this.updateItemState}
onAddNew={this.handleAddNew}
isSubmitting={isSubmitting}
error={error}
/>
)}
{this.props.student && (
<h6>You have added a new student named: {this.props.student.name}</h6>
)}
</Container>
);
}
}
const mapStateToProps = state => {
return {
isSubmitting: state.studentReducer.isSubmitting,
error: state.studentReducer.error,
student: state.studentReducer.student
};
};
const mapDispatchToProps = {
addStudentAction: item => addStudentAction(item)
};
或者您可以使用
getDerivedStateFromProps
lifecycle方法重新计算props。但是我发现它比组件diddupdate
更难使用 实现这一点有点复杂和笨拙,但您仍然可以按如下方式强制执行该行为:
在行动中使用承诺
:
export const addStudentAction = item => {
return function(dispatch) {
dispatch({ type: 'STUDENT_ADD_BEGIN' });
setTimeout(() => {
if (item.name !== 'error') {
// HERE
Promise.resolve(
dispatch({ type: 'STUDENT_ADD_SUCCESS', payload: item })
);
dispatch(closeModal('AddStudentModal'));
} else {
// HERE
Promise.resolve(
dispatch({
type: 'STUDENT_ADD_ERROR',
error: 'Intentional Error Message'
})
);
}
}, 1000);
};
};
将允许您在保存项目后立即链接设置状态
,并关闭模式:
handleAddNew = () => {
let item = this.state.dataItem;
item['id'] = uuid.v4();
this.props.dispatch(addStudentAction(item)).then(() => {
console.log('boom');
this.setState({ add: false });
});
};
请注意,为了做到这一点,您需要为每个操作显式地在操作上使用dispatch
,而不是使用mapDispatchToProps
我已修改了,以便您可以检查所需的行为。谢谢您的建议。但是,它不起作用。今天早上,我将ui状态提升到Redux上,并意外地重写了CodeSandbox。这就是为什么当你尝试的时候它会起作用。我分叉并回滚了我最近的更改,并按照您的建议在这个新的代码沙盒中应用。您可以注意到,它甚至不会触发调度。好的,然后修改您的减速机。如果要从减速器控制模态,应在modalReducer中将isAddStudentModalOpen从true切换为false,就像之前在状态中使用this.props.add所做的那样。例子:
componentDidUpdate(prevProps) {
const { isSubmitting, error } = this.props;
if (isSubmitting !== prevProps.isSubmitting || error !== prevProps.error) {
if (isSubmitting === false && error === null)
this.setState({ add: false });
}
}
export const addStudentAction = item => {
return function(dispatch) {
dispatch({ type: 'STUDENT_ADD_BEGIN' });
setTimeout(() => {
if (item.name !== 'error') {
// HERE
Promise.resolve(
dispatch({ type: 'STUDENT_ADD_SUCCESS', payload: item })
);
dispatch(closeModal('AddStudentModal'));
} else {
// HERE
Promise.resolve(
dispatch({
type: 'STUDENT_ADD_ERROR',
error: 'Intentional Error Message'
})
);
}
}, 1000);
};
};
handleAddNew = () => {
let item = this.state.dataItem;
item['id'] = uuid.v4();
this.props.dispatch(addStudentAction(item)).then(() => {
console.log('boom');
this.setState({ add: false });
});
};