如何使用 React redux 和模态形式刷新 table 中的数据?
How can refresh data in a table using react redux and a modal form?
我在使用 react/redux 和表单刷新 table 中的数据时遇到问题。我在这里需要做的是填写模态表单,然后提交到我的后端,然后使用 setState 刷新 table。我可以做所有事情,例如渲染 table、显示模态、提交数据,但是当模态关闭时我无法刷新 table 中的数据。我怎样才能用 redux 得到这个结果?
import React, {useState} from 'react';
import ContainerHeader from 'components/ContainerHeader/index';
import IntlMessages from "../../../util/IntlMessages";
import {useDispatch, useSelector, shallowEqual} from 'react-redux';
import {
getBanksFromBackend,
storeBankBackend,
updateBankBackend,
deleteBankBackend,
} from '../../../actions';
import MaterialTable, {MTableToolbar} from "material-table";
import CardBox from "../../../components/CardBox";
import FormDialog from "./FormDialog";
import TextFields from "./TextFields";
const BanksPage = ({match}) => {
const dispatch = useDispatch();
const allBanks = useSelector(state => state.banks, shallowEqual);
const [state, setState] = useState({
columns: [
{
title: 'Avatar',
field: 'imageUrl',
render: rowData => <img src={rowData.imageUrl} style={{width: 30, borderRadius: '50%'}}/>
},
{title: 'ID', field: 'id', editable: 'never'},
{title: 'Bank Name', field: 'bnk_name'},
{title: 'Bank Iban', field: 'bnk_iban'},
{title: 'Bank BIC', field: 'bnk_bic'},
],
data: allBanks.banks.map(bank => {
return (
{
imageUrl: 'https://img.icons8.com/office/80/000000/user.png',
id: bank.id,
bnk_name: bank.bnk_name,
bnk_iban: bank.bnk_iban,
bnk_bic: bank.bnk_bic,
}
)
})
});
return (
<div className="app-wrapper">
<ContainerHeader match={match} title={<IntlMessages id="pages.banks"/>}/>
<div className="row">
<CardBox styleName="col-lg-12">
<MaterialTable
title="Users Table"
columns={state.columns}
data={state.data}
options={{
exportButton: true,
grouping: true,
selection: true
}}
components={{
Toolbar: props => (
<div>
<MTableToolbar {...props} />
<div style={{padding: '0px 10px'}}>
<div className="card d-inline-block">
<FormDialog {...state}/>
</div>
</div>
</div>
),
}}
/>
</CardBox>
</div>
</div>
)
}
export default BanksPage;
这是模态组件
import React, {useState} from 'react';
import Button from '@material-ui/core/Button';
import TextField from '@material-ui/core/TextField';
import Dialog from '@material-ui/core/Dialog';
import DialogActions from '@material-ui/core/DialogActions';
import DialogContent from '@material-ui/core/DialogContent';
import DialogContentText from '@material-ui/core/DialogContentText';
import DialogTitle from '@material-ui/core/DialogTitle';
import {useDispatch, useSelector, shallowEqual} from "react-redux";
import {getBanksFromBackend, storeBankBackend} from "../../../actions";
const FormDialog = (props) => {
console.log('Proprietà passate al form: ', props);
const dispatch = useDispatch();
const initModalState = {
open: false,
};
const [modalState, setModalState] = useState(initModalState);
const [bankName, setBankName] = useState('');
const [bankIban, setBankIban] = useState('');
const [bankBic, setBankBic] = useState('');
const [tableState, setTableState] = useState(props);
console.log('Stato iniziale Tabella:', tableState);
const handleClickOpen = () => {
setModalState({open: true})
};
const handleRequestClose = () => {
setModalState({open: false})
};
return (
<div>
<Button variant="contained" className="bg-primary text-white" onClick={() => handleClickOpen()}>Add
Bank</Button>
<form>
<Dialog open={modalState.open} onClose={() => handleRequestClose()}>
<DialogTitle>Subscribe</DialogTitle>
<DialogContent>
<DialogContentText>
Add Bank from Form.
</DialogContentText>
<TextField
autoFocus
margin="dense"
id="bnk_name"
label="Bank Name"
type="text"
fullWidth
onChange={(event) => setBankName(event.target.value)}
defaultValue={bankName}
/>
<TextField
autoFocus
margin="dense"
id="bnk_iban"
label="Bank Iban"
type="text"
fullWidth
onChange={(event) => setBankBic(event.target.value)}
defaultValue={bankIban}
/>
<TextField
autoFocus
margin="dense"
id="bnk_bic"
label="Bank BIC"
type="text"
fullWidth
onChange={(event) => setBankIban(event.target.value)}
defaultValue={bankBic}
/>
</DialogContent>
<DialogActions>
<Button onClick={() => handleRequestClose()} color="secondary">
Cancel
</Button>
<Button onClick={() => handleRequestClose()} color="primary">
Submit
</Button>
<Button onClick={() => new Promise((resolve) => {
setTimeout(() => {
resolve();
dispatch(storeBankBackend
({
bnk_name: bankName,
bnk_iban: bankIban,
bnk_bic: bankBic
}
)
);
dispatch(getBanksFromBackend());
handleRequestClose();
}, 2000)
})} color="primary">
Submit Bank
</Button>
</DialogActions>
</Dialog>
</form>
</div>
);
}
export default FormDialog;
我认为您正在克隆 BanksPage functional component
中的 redux 状态。在 React 组件中,状态是在构造函数中定义的,所以你只是在第一次渲染时分配它们。
稍后,FormDialog component
中的调度(可能)通过成功调用操作(如 orangespark 所建议的那样,您确定调度有效吗?您应该向我们展示您的操作和减速器),但是组件不会更新,因为您正在渲染 BanksPage
组件中记忆的状态克隆。
建议您尝试从状态挂钩中移出列和数据对象,如果只使用 redux 状态,则不需要,然后将它们分配给变量
我在使用 react/redux 和表单刷新 table 中的数据时遇到问题。我在这里需要做的是填写模态表单,然后提交到我的后端,然后使用 setState 刷新 table。我可以做所有事情,例如渲染 table、显示模态、提交数据,但是当模态关闭时我无法刷新 table 中的数据。我怎样才能用 redux 得到这个结果?
import React, {useState} from 'react';
import ContainerHeader from 'components/ContainerHeader/index';
import IntlMessages from "../../../util/IntlMessages";
import {useDispatch, useSelector, shallowEqual} from 'react-redux';
import {
getBanksFromBackend,
storeBankBackend,
updateBankBackend,
deleteBankBackend,
} from '../../../actions';
import MaterialTable, {MTableToolbar} from "material-table";
import CardBox from "../../../components/CardBox";
import FormDialog from "./FormDialog";
import TextFields from "./TextFields";
const BanksPage = ({match}) => {
const dispatch = useDispatch();
const allBanks = useSelector(state => state.banks, shallowEqual);
const [state, setState] = useState({
columns: [
{
title: 'Avatar',
field: 'imageUrl',
render: rowData => <img src={rowData.imageUrl} style={{width: 30, borderRadius: '50%'}}/>
},
{title: 'ID', field: 'id', editable: 'never'},
{title: 'Bank Name', field: 'bnk_name'},
{title: 'Bank Iban', field: 'bnk_iban'},
{title: 'Bank BIC', field: 'bnk_bic'},
],
data: allBanks.banks.map(bank => {
return (
{
imageUrl: 'https://img.icons8.com/office/80/000000/user.png',
id: bank.id,
bnk_name: bank.bnk_name,
bnk_iban: bank.bnk_iban,
bnk_bic: bank.bnk_bic,
}
)
})
});
return (
<div className="app-wrapper">
<ContainerHeader match={match} title={<IntlMessages id="pages.banks"/>}/>
<div className="row">
<CardBox styleName="col-lg-12">
<MaterialTable
title="Users Table"
columns={state.columns}
data={state.data}
options={{
exportButton: true,
grouping: true,
selection: true
}}
components={{
Toolbar: props => (
<div>
<MTableToolbar {...props} />
<div style={{padding: '0px 10px'}}>
<div className="card d-inline-block">
<FormDialog {...state}/>
</div>
</div>
</div>
),
}}
/>
</CardBox>
</div>
</div>
)
}
export default BanksPage;
这是模态组件
import React, {useState} from 'react';
import Button from '@material-ui/core/Button';
import TextField from '@material-ui/core/TextField';
import Dialog from '@material-ui/core/Dialog';
import DialogActions from '@material-ui/core/DialogActions';
import DialogContent from '@material-ui/core/DialogContent';
import DialogContentText from '@material-ui/core/DialogContentText';
import DialogTitle from '@material-ui/core/DialogTitle';
import {useDispatch, useSelector, shallowEqual} from "react-redux";
import {getBanksFromBackend, storeBankBackend} from "../../../actions";
const FormDialog = (props) => {
console.log('Proprietà passate al form: ', props);
const dispatch = useDispatch();
const initModalState = {
open: false,
};
const [modalState, setModalState] = useState(initModalState);
const [bankName, setBankName] = useState('');
const [bankIban, setBankIban] = useState('');
const [bankBic, setBankBic] = useState('');
const [tableState, setTableState] = useState(props);
console.log('Stato iniziale Tabella:', tableState);
const handleClickOpen = () => {
setModalState({open: true})
};
const handleRequestClose = () => {
setModalState({open: false})
};
return (
<div>
<Button variant="contained" className="bg-primary text-white" onClick={() => handleClickOpen()}>Add
Bank</Button>
<form>
<Dialog open={modalState.open} onClose={() => handleRequestClose()}>
<DialogTitle>Subscribe</DialogTitle>
<DialogContent>
<DialogContentText>
Add Bank from Form.
</DialogContentText>
<TextField
autoFocus
margin="dense"
id="bnk_name"
label="Bank Name"
type="text"
fullWidth
onChange={(event) => setBankName(event.target.value)}
defaultValue={bankName}
/>
<TextField
autoFocus
margin="dense"
id="bnk_iban"
label="Bank Iban"
type="text"
fullWidth
onChange={(event) => setBankBic(event.target.value)}
defaultValue={bankIban}
/>
<TextField
autoFocus
margin="dense"
id="bnk_bic"
label="Bank BIC"
type="text"
fullWidth
onChange={(event) => setBankIban(event.target.value)}
defaultValue={bankBic}
/>
</DialogContent>
<DialogActions>
<Button onClick={() => handleRequestClose()} color="secondary">
Cancel
</Button>
<Button onClick={() => handleRequestClose()} color="primary">
Submit
</Button>
<Button onClick={() => new Promise((resolve) => {
setTimeout(() => {
resolve();
dispatch(storeBankBackend
({
bnk_name: bankName,
bnk_iban: bankIban,
bnk_bic: bankBic
}
)
);
dispatch(getBanksFromBackend());
handleRequestClose();
}, 2000)
})} color="primary">
Submit Bank
</Button>
</DialogActions>
</Dialog>
</form>
</div>
);
}
export default FormDialog;
我认为您正在克隆 BanksPage functional component
中的 redux 状态。在 React 组件中,状态是在构造函数中定义的,所以你只是在第一次渲染时分配它们。
稍后,FormDialog component
中的调度(可能)通过成功调用操作(如 orangespark 所建议的那样,您确定调度有效吗?您应该向我们展示您的操作和减速器),但是组件不会更新,因为您正在渲染 BanksPage
组件中记忆的状态克隆。
建议您尝试从状态挂钩中移出列和数据对象,如果只使用 redux 状态,则不需要,然后将它们分配给变量