[英]How to close the Modal Dialog when state changed in React-Redux?
Basically, I want to change the UI state in the Component when the Global state has been changed in the Redux-Store. 基本上,我想在Redux-Store中更改Global状态时更改Component中的UI状态。
My scenario is as follow: 我的方案如下:
I have achieved the first 3 points, but I'm stuck at the 4th point and don't know how to implement the Close
feature after the successful insertion. 我已经达到了前3分,但我在第4点陷入困境,并且在成功插入后不知道如何实现
Close
功能。
I would like to run the following example code whenever isSubmitting/error has been changed in the Redux-Store. 我想在Redux-Store中更改isSubmitting / error时运行以下示例代码。 But, I don't know where to run it.
但是,我不知道在哪里运行它。 I tried to put it in the render() method, but it doesn't work and I couldn't open the dialog anymore.
我试图将它放在render()方法中,但它不起作用,我无法打开对话框。
Code to Check and Close the Modal 检查和关闭模态的代码
if (isSubmitting === false && error === null)
this.setState({ add: false });
I don't want to lift that UI state (Eg. IsModalOpen - bool) into the Global Redux store. 我不想将UI状态(例如IsModalOpen - bool)提升到Global Redux商店。 I have already put the UI state 'isSubmitting' into Redux and I don't want to keep adding UI states into the Redux Store.
我已经将UI状态'isSubmitting'放入Redux中,我不想继续将UI状态添加到Redux Store中。
Could you please suggest me how I can close the dialog after the successful insertion? 您能否建议我在成功插入后如何关闭对话框?
I put the sample code on the CodeSandbox and it's here 我把示例代码放在CodeSandbox上,就在这里
Reducer 减速器
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;
Container/Page 集装箱/页
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)
};
Modal Form 模态表格
export default class StudentAdd extends Component {
render() {
const {
modal,
toggle,
item,
onChange,
onAddNew,
isSubmitting,
error
} = this.props;
return (
<Modal isOpen={modal} toggle={toggle} centered>
<ModalHeader toggle={toggle}>Add New Student</ModalHeader>
<ModalBody>
{error && <Alert color="danger">{error}</Alert>}
<Form>
<FormGroup>
<Label for="Name">Name</Label>
<Input
type="text"
name="name"
id="Name"
value={item.name}
onChange={onChange}
/>{" "}
type 'error' to simulate error
</FormGroup>
</Form>
</ModalBody>
<ModalFooter>
<Button color="primary" onClick={onAddNew} disabled={isSubmitting}>
{isSubmitting ? "Saving..." : "Save"}
</Button>{" "}
<Button color="secondary" onClick={toggle}>
Cancel
</Button>
</ModalFooter>
</Modal>
);
}
}
UPDATES 更新
It can be achieved by using componentDidUpdate
lifecycle method as below: please be careful that you check the props and states correctly before deriving the state. 它可以通过使用
componentDidUpdate
生命周期方法来实现,如下所示:在导出状态之前,请注意检查道具和状态。
componentDidUpdate(prevProps) {
const { isSubmitting, error } = this.props;
if (isSubmitting !== prevProps.isSubmitting || error !== prevProps.error) {
if (isSubmitting === false && error === null)
this.setState({ add: false });
}
}
Or you can use getDerivedStateFromProps
lifecycle method to re-calculate the props. 或者您可以使用
getDerivedStateFromProps
生命周期方法重新计算道具。 But I found it difficult to use than componentDidUpdate
. 但我发现很难使用
componentDidUpdate
。
It is bit more complex and clumsy to achieve that, but you can still force that behavior as follow: 实现这一点有点复杂和笨拙,但你仍然可以强制执行以下行为:
Using Promise
on your action: 在行动中使用
Promise
:
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);
};
};
Will let you chain your setState
and close the modal right after saving the item: 在保存项目后,可以让你链接你的
setState
并关闭模态:
handleAddNew = () => {
let item = this.state.dataItem;
item['id'] = uuid.v4();
this.props.dispatch(addStudentAction(item)).then(() => {
console.log('boom');
this.setState({ add: false });
});
};
Note that in order to do so, you will need to use dispatch
on your actions explicitly for each action, instead of using mapDispatchToProps
. 需要注意的是,为了做到这一点,你就需要使用
dispatch
明确你的行动的每一个动作,而不是使用mapDispatchToProps
。
I have modified the codesandbox so you can inspect the desired behavior. 我修改了代码框,以便您可以检查所需的行为。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.