React-Redux:重新渲染太多
React-Redux: Too many re-renders
在我的 react/redux 应用程序中,我试图让 AddBoxIcon 在单击时弹出 Modal
。目前我收到一个错误
Error: Too many re-renders. React limits the number of renders to prevent an infinite loop.
第二个问题,我怀疑我配置 toggleModal 操作的方式可能是错误的。
我的方法不行。
// Toggle Modal action
export const toggleModal = () => (dispatch) => {
dispatch({
type: TOGGLE_MODAL,
});
};
// Invoice Reducer
const initialState = {
invoiceData: [],
newInvoiceModal: false,
};
export default function (state = initialState, action) {
switch (action.type) {
case TOGGLE_MODAL:
return {
...state,
newInvoiceModal: !state.newInvoiceModal
};
case GET_INVOICE_DATA:
return {
...state,
invoiceData: action.payload,
};
case ADD_INVOICE_DATA:
return {
...state,
invoiceData: action.payload,
};
default:
return state;
}
}
发票table组件
import AddInvoiceModal from './AddInvoiceModal'
import { getInvoiceData, toggleModal } from "../../actions/customers/invoice";
const InvoiceTable = (props) => {
const invoiceData = useSelector((state) => state.invoice.invoiceData);
const newInvoiceModal = useSelector((state) => state.invoice.newInvoiceModal);
const dispatch = useDispatch();
useEffect(() => {
dispatch(getInvoiceData());
}, [dispatch]);
const classes = useStyles();
const columns = [
{ name: "date", label: "Date" },
{ name: "invoiceOwner", label: "Name" },
{ name: "invoiceNo", label: "Invoice No" },
{ name: "product", label: "Product" },
];
return (
<div className={classes.root}>
{/* ADD NEW EMPLOYEE MODAL */}
<AddInvoiceModal
toggleModal={dispatch(toggleModal())}
newInvoiceModal={newInvoiceModal}
/>
<Grid container spacing={3}>
<Grid item xs={12}>
<Paper className={classes.paper}>
<MUIDataTable
title={
<Fragment>
Purchase Invoice
<Tooltip title="Add">
<AddBoxIcon <===== ADD ICON
color="action"
style={addIcon}
onClick={dispatch(toggleModal())} <===== MODAL TRIGGER
/>
</Tooltip>
</Fragment>
}
data={invoiceData}
columns={columns}
options={options}
/>
</Paper>
</Grid>
</Grid>
</div>
);
};
InvoiceTable.propTypes = {
invoiceData: PropTypes.object.isRequired,
getInvoiceData: PropTypes.func,
toggleModal: PropTypes.func,
newInvoiceModal: PropTypes.bool,
};
export default InvoiceTable;
模态文件
const AddInvoiceModal = (props) => {
return (
<div className="App container">
<Modal isOpen={props.newInvoiceModal} scrollable={true}>
<ModalHeader toggle={props.toggleModal}>Add Invoice</ModalHeader>
<ModalBody>
<h2>Hello</h2>
</ModalBody>
<ModalFooter>
<Button
color="primary"
>
Submit
</Button>{" "}
<Button
color="secondary"
>
Cancel
</Button>
</ModalFooter>
</Modal>
</div>
);
}
export default AddInvoiceModal;
老实说,我认为唯一的问题是这个
toggleModal={dispatch(toggleModal())}
需要
toggleModal={() => dispatch(toggleModal())}
现在每个渲染器都会调用 dispatch(toggleModal())
这将导致 re-render 再次调用它
在我的 react/redux 应用程序中,我试图让 AddBoxIcon 在单击时弹出 Modal
。目前我收到一个错误
Error: Too many re-renders. React limits the number of renders to prevent an infinite loop.
第二个问题,我怀疑我配置 toggleModal 操作的方式可能是错误的。
我的方法不行。
// Toggle Modal action
export const toggleModal = () => (dispatch) => {
dispatch({
type: TOGGLE_MODAL,
});
};
// Invoice Reducer
const initialState = {
invoiceData: [],
newInvoiceModal: false,
};
export default function (state = initialState, action) {
switch (action.type) {
case TOGGLE_MODAL:
return {
...state,
newInvoiceModal: !state.newInvoiceModal
};
case GET_INVOICE_DATA:
return {
...state,
invoiceData: action.payload,
};
case ADD_INVOICE_DATA:
return {
...state,
invoiceData: action.payload,
};
default:
return state;
}
}
发票table组件
import AddInvoiceModal from './AddInvoiceModal'
import { getInvoiceData, toggleModal } from "../../actions/customers/invoice";
const InvoiceTable = (props) => {
const invoiceData = useSelector((state) => state.invoice.invoiceData);
const newInvoiceModal = useSelector((state) => state.invoice.newInvoiceModal);
const dispatch = useDispatch();
useEffect(() => {
dispatch(getInvoiceData());
}, [dispatch]);
const classes = useStyles();
const columns = [
{ name: "date", label: "Date" },
{ name: "invoiceOwner", label: "Name" },
{ name: "invoiceNo", label: "Invoice No" },
{ name: "product", label: "Product" },
];
return (
<div className={classes.root}>
{/* ADD NEW EMPLOYEE MODAL */}
<AddInvoiceModal
toggleModal={dispatch(toggleModal())}
newInvoiceModal={newInvoiceModal}
/>
<Grid container spacing={3}>
<Grid item xs={12}>
<Paper className={classes.paper}>
<MUIDataTable
title={
<Fragment>
Purchase Invoice
<Tooltip title="Add">
<AddBoxIcon <===== ADD ICON
color="action"
style={addIcon}
onClick={dispatch(toggleModal())} <===== MODAL TRIGGER
/>
</Tooltip>
</Fragment>
}
data={invoiceData}
columns={columns}
options={options}
/>
</Paper>
</Grid>
</Grid>
</div>
);
};
InvoiceTable.propTypes = {
invoiceData: PropTypes.object.isRequired,
getInvoiceData: PropTypes.func,
toggleModal: PropTypes.func,
newInvoiceModal: PropTypes.bool,
};
export default InvoiceTable;
模态文件
const AddInvoiceModal = (props) => {
return (
<div className="App container">
<Modal isOpen={props.newInvoiceModal} scrollable={true}>
<ModalHeader toggle={props.toggleModal}>Add Invoice</ModalHeader>
<ModalBody>
<h2>Hello</h2>
</ModalBody>
<ModalFooter>
<Button
color="primary"
>
Submit
</Button>{" "}
<Button
color="secondary"
>
Cancel
</Button>
</ModalFooter>
</Modal>
</div>
);
}
export default AddInvoiceModal;
老实说,我认为唯一的问题是这个
toggleModal={dispatch(toggleModal())}
需要
toggleModal={() => dispatch(toggleModal())}
现在每个渲染器都会调用 dispatch(toggleModal())
这将导致 re-render 再次调用它