'Redux-toolkit useSelector doesn't update
So I use redux-toolkit for a form. The form is made up of 3 tabs. Each tab has some inputs. I store the errors and values in redux. After I save the form, saveFrom is called, but the redux state doesn't update only after it rerendered or I click save again.
So basically It only shows the right data on every second save. Why is that? Doesn't the useSelector need to update when it's state changes?
ProgressSlice:
import { createSlice, current } from "@reduxjs/toolkit";
export const progressSlice = createSlice({
name: "progress",
initialState: {
errors: {},
results: {}
},
reducers: {
addErrorById: (state, { payload: action }) => {
const { text, id } = action
//console.log(current(state).errors[id])
state.errors = {
...state.errors,
[id]: [
text
]
}
},
deleteErrorById: (state, { payload: id }) => {
delete state.errors[id]
},
createResult: (state, { payload }) => {
const { id, type, required } = payload
state.results = {
...state.results,
[id]: {
"id": id,
"value": (type === 'boolean' || required === false) ? 0 : null
}
}
},
addResult: (state, { payload }) => {
const { formValue, id, type } = payload
let value = null;
if (type === 'list') {
const { good, bad } = formValue;
good ? value = good : value = bad;
} else {
value = formValue * 1
}
state.results = {
...state.results,
[id]: {
"id": id,
"value": value
}
}
}
}
})
export const { addErrorById, deleteErrorById, addResult, createResult } = progressSlice.actions;
export const progressReducer = progressSlice.reducer;
TabContent.js:
export default function TabContent({ task }) {
const res = useSelector((state) => state.progress.results);
const err = useSelector((state) => state.progress.errors);
const progressDispatch = useDispatch()
const totalScore = useSelector((state) => state.score.count);
const Scoredispatch = useDispatch()
const formDispatch = useDispatch()
const formData = useSelector((state) => state.form.tasks);
const [formValues, setFormValues] = useState(
task.reduce((prev, curr) => {
const value = formData[curr.id] ? formData[curr.id].formValue : null;
return {
...prev,
[curr.id]: {
...curr,
formValue: value
}
}
}, {})
);
const canSubmit = () => {
// But here it doesn't seem to be updated
console.log("SUBMIT",res)
console.log("ERRS",err)
const can = Object.entries(res).every((result) => result[1].value !== null)
&& Object.keys(err).length === 0
if(can) console.log("CAN SAVE")
else console.log("CANNOT SAVE")
}
const saveFrom = (e) => {
e.preventDefault()
console.log("SAVE")
Object.entries(formValues).forEach(([key, e]) => {
//console.log(e)
let isError = false
if (e.type === 'number') {
if (e.formValue !== null && e.formValue !== '')
const val = e.formValue;
if (Number.isFinite(val * 1)) {
if (!(val <= e.maxValue && val >= 0)) {
progressDispatch(addErrorById({ 'text': Errors.OUTOFRANGE + e.maxValue + Errors.TEXTHELP, 'id': e.id }))
isError = true;
}
} else {
progressDispatch(addErrorById({ 'text': Errors.NOTNUM, 'id': e.id }))
isError = true;
}
} else if (e.required) {
progressDispatch(addErrorById({ 'text': Errors.REQUIRED, 'id': e.id }))
isError = true;
}
} else if (e.type === 'list') {
if (e.formValue === null && e.required) {
//console.log("EZ")
progressDispatch(addErrorById({ 'text': Errors.REQUIRED, 'id': e.id }))
isError = true;
}
}
if(!isError){
// Here I update redux-state
progressDispatch(deleteErrorById(e.id))
progressDispatch(addResult(e))
formDispatch(setValueById(e))
}
})
canSubmit()
}
return (
<form>
<Table>
<TableHead>
<TableRow>
<TableCell>#</TableCell>
<TableCell>Szempont megnevezése</TableCell>
<TableCell>{task[0] ? getColLabel() : "Nincs szempont"}</TableCell>
<TableCell>Szempont leírása</TableCell>
</TableRow>
</TableHead>
<TableBody>
{task.map((row) => (
<TableRow
key={row.name}
>
<TableCell>{row.id}</TableCell>
<TableCell>{row.name}</TableCell>
<TableCell>{getGradingType(row, formValues, setFormValues)}</TableCell>
<TableCell>{row.description ? row.description : 'Nincs leírás'}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
{task[0] && <FormActions save={saveFrom}></FormActions>}
<div>{totalScore}</div>
</form>
)
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
