如果不使用redux重新加载页面,就无法在发生新更改时更新表



我在同一页中有两个表组件:Resolved CasesAffected Cases。每当我更新Affected Cases表中的一行并对其进行验证时,它都会显示在Resolved Cases组件上。

AffectedCases.tsx:

import React, { useEffect } from 'react';
import { useDispatch, useSelector, shallowEqual } from "react-redux";
import MaterialTable, { Column } from 'material-table';
import TableIcons from "../../common/TableIcons";
import {
fetchAffectedCasesRequest,
updateAffectedCaseRequest
} from "./affectedCasesSlice";
import { AppState } from "../../app/rootReducer";
interface Row {
caseId: number;
name: string;
email: string;
bikeFrameNumber: number;
caseResolved: number;
}
const AffectedCasesList = () => {
const dispatch = useDispatch();
const { officerId, cases } = useSelector((state: AppState) => ({
officerId: state.affectedCases.officerId,
cases: state.affectedCases.cases
}), shallowEqual)
const data = cases.map(c => ({ ...c }));
const columns: Column<Row>[] = [
{ title: 'Case Id', field: 'caseId', type: 'numeric', editable: 'never' },
{ title: 'Name', field: 'name', editable: 'never' },
{ title: 'Email', field: 'email', editable: 'never' },
{ title: 'Bike Frame Number', field: 'bikeFrameNumber', type: 'numeric', editable: 'never' },
{ title: 'Case Resolved', field: 'caseResolved', lookup: { 1: 'true', 0: 'false' } }
];
useEffect(() => {
dispatch(fetchAffectedCasesRequest(officerId))
}, [officerId, dispatch])
return (
<MaterialTable
icons={TableIcons}
columns={columns}
data={data}
editable={{
onRowUpdate: (newData, oldData) => new Promise((resolve, reject) => {
setTimeout(() => {
resolve();
if (newData.caseResolved) {
dispatch(updateAffectedCaseRequest({
caseId: newData.caseId,
officerId
}))
}
}, 1000)
}),
}}
options={{
showTitle: false,
rowStyle: {
color: '#ffd600'
}
}}
style={{
width: '100%',
backgroundColor: '#111010'
}}
/>
);
}
export default AffectedCasesList;

受影响的案例:

import { AppThunk } from "../../app/store";
import {
ReturnedCase,
resolveCaseApi,
AffectedCaseToUpdate,
affectedCasesApi,
} from "../../api/reportedCasesApi";
interface AffectedCasesState {
officerId: number;
loading: boolean;
cases: ReturnedCase[];
error: string | null;
}
const initialState: AffectedCasesState = {
officerId: 1,
loading: false,
cases: [],
error: null
}

const affectedCase = createSlice({
name: 'affectedCase',
initialState,
reducers: {
officerCaseStart: (state) => {
state.error = null;
},
startAffectedCasesFetch: (state) => {
state.loading = true
},
fetchAffectedCasesSuccess: (state, action: PayloadAction<ReturnedCase[]>) => {
state.cases = action.payload;
state.loading = false;
},
updateAffectedCaseSuccess: (state, action: PayloadAction<number>) => {
state.cases = state.cases.filter(c => c.caseId !== action.payload)
},
updateAffectedCaseError: (state, action: PayloadAction<string>) => {
state.error = action.payload;
},
fetchAffectedCaseError: (state, action: PayloadAction<string>) => {
state.error = action.payload;
state.loading = false;
},
}
})
export const {
officerCaseStart,
startAffectedCasesFetch,
fetchAffectedCasesSuccess,
fetchAffectedCaseError,
updateAffectedCaseError,
updateAffectedCaseSuccess
} = affectedCase.actions

export default affectedCase.reducer;

export const updateAffectedCaseRequest = (caseToUpdate: AffectedCaseToUpdate): AppThunk => async dispatch => {
try {
dispatch(officerCaseStart());
const updatedCaseId = await resolveCaseApi(caseToUpdate);
dispatch(updateAffectedCaseSuccess(updatedCaseId))
} catch (error) {
let errorMessage = "Internal Server Error";
if (error.response) {
errorMessage = error.response.data.message;
}
dispatch(updateAffectedCaseError(errorMessage))
}
}
export const fetchAffectedCasesRequest = (officerId: number): AppThunk => async dispatch => {
try {
dispatch(startAffectedCasesFetch())
const affectedCasesList = await affectedCasesApi(officerId);
dispatch(fetchAffectedCasesSuccess(affectedCasesList))
} catch (error) {
let errorMessage = "Internal Server Error";
if (error.response) {
errorMessage = error.response.data.message;
}
dispatch(fetchAffectedCaseError(errorMessage))
}
}

ResolvedCases.tsx:

import React, { useEffect } from 'react';
import { useDispatch, useSelector, shallowEqual } from "react-redux";
import MaterialTable, { Column } from 'material-table';
import TableIcons from "../../common/TableIcons";
import {
fetchResolvedCasesRequest
} from "./resolvedCasesSlice";
import { AppState } from "../../app/rootReducer";
interface Row {
caseId: number;
name: string;
email: string;
bikeFrameNumber: number;
}
const ResolvedCasesList = () => {
const dispatch = useDispatch();
const { officerId, cases } = useSelector((state: AppState) => ({
officerId: state.resolvedCases.officerId,
cases: state.resolvedCases.cases
}), shallowEqual);
const data = cases.map(c => ({ ...c }));
const columns: Column<Row>[] = [
{ title: 'Case Id', field: 'caseId', type: 'numeric' },
{ title: 'Name', field: 'name' },
{ title: 'Email', field: 'email' },
{ title: 'Bike Frame Number', field: 'bikeFrameNumber', type: 'numeric' },
];
useEffect(() => {
dispatch(fetchResolvedCasesRequest(officerId))
}, [officerId, dispatch])
return (
<MaterialTable
icons={TableIcons}
columns={columns}
data={data}
options={{
showTitle: false,
rowStyle: {
color: '#ffd600'
}
}}
style={{
width: '100%',
backgroundColor: '#111010'
}}
/>
);
}
export default ResolvedCasesList;

resolvedCasesSlice.ts:

import { createSlice, PayloadAction } from "@reduxjs/toolkit";
import { AppThunk } from "../../app/store";
import {
BasicResult,
resolvedCasesApi
} from "../../api/reportedCasesApi";
interface CasesState {
officerId: number;
loading: boolean;
cases: BasicResult[];
error: string | null;
}
const initialState: CasesState = {
officerId: 1,
loading: false,
cases: [],
error: null
}

const resolvedCases = createSlice({
name: 'resolvedCases',
initialState,
reducers: {
startResolvedCasesFetch: (state) => {
state.loading = true
},
fetchResolvedCasesSuccess: (state, action: PayloadAction<BasicResult[]>) => {
state.cases = action.payload;
state.loading = false;
},
fetchResolvedCaseError: (state, action: PayloadAction<string>) => {
state.error = action.payload;
state.loading = false;
}
}
})
export const {
startResolvedCasesFetch,
fetchResolvedCasesSuccess,
fetchResolvedCaseError,
} = resolvedCases.actions

export default resolvedCases.reducer;

export const fetchResolvedCasesRequest = (officerId: number): AppThunk => async dispatch => {
try {
dispatch(startResolvedCasesFetch())
const resolvedCasesList = await resolvedCasesApi(officerId);
dispatch(fetchResolvedCasesSuccess(resolvedCasesList));
} catch (error) {
let errorMessage = "Internal Server Error";
if (error.response) {
errorMessage = error.response.data.message;
}
dispatch(fetchResolvedCaseError(errorMessage))
}
}

ResolvedCases组件只有在我刷新页面时才会更新,原因是:

useEffect(() => {
dispatch(fetchResolvedCasesRequest(officerId))
}, [officerId, dispatch])

有没有任何解决方案可以在不刷新页面的情况下更新ResolvedCases表?

每次更新受影响案例中的一行时,带有dispatch的useEffect都应该激发。因此,例如,当发生这种情况时,您可以发送带有一些修订ID的操作,并将您的useEffect重写为:

const revisionIdPrev = useRef(props.revisionId)
useEffect(() => {
if (revisionId !== revisionIdPrev.current) {
dispatch(fetchResolvedCasesRequest(officerId))
revisionIdPrev.current = revisionId
}
}, [officerId, dispatch, revisionId])

相关内容

  • 没有找到相关文章

最新更新