Reputation: 133
I've been battling this all day long and I'd appreciate any help.
I have a redux store built with Redux Toolkit and createSlice that looks like so:
const initialState = {
analiticaNumber: "",
animal: {},
tests: [{ key: "G9116", value: "DERMATOFITOS PCR/ MUESTRA" }],
};
const PeticionSlice = createSlice({
name: "peticion",
initialState,
reducers: {
addTest: (state, action) => {
state.tests.push(action.payload);
},
},
});
export const { addTest: addTestActionCreator } = PeticionSlice.actions;
export const testsArray = (state) => state.Peticion.tests;
export default PeticionSlice.reducer;
I also have a root reducer that imports the rest of the slices and names them as such
import { combineReducers } from "redux";
import NavigationSlice from "./NavigationSlice";
const RootReducer = combineReducers({
Peticion: PeticionSlice,
});
export default RootReducer;
When I add tests to the tests array it works fine and shows in the redux devtools.
The promblem comes that react does not see the change in the store and won't update the child component:
import { testsArray } from "./Store/PeticionSlice";
That's how I import namely the testsArray to call with the useSelector.
The tradicional way of const { tests } = useSelector( (state) => state.Peticion)
doesn't work either.
function App() {
const tests = useSelector(testsArray);
useEffect(() => {
console.log("tests");
}, [tests]);
return (
<StylesProvider injectFirst>
<div className="App">
<nav>
<Navbar />
</nav>
{tests.map((test) => (
<p>{test.key}</p>
))}
</div>
</StylesProvider>
);
}
I belive it has to do something with the mutability of the state, but I thought the toolkit took care of that, and for the life of me I don't know how to solve this.
Any help??? Thanks a lot.
** UPDATE **
I believe it has to do with the way I dispatch the actions. Because I needed to add several boundaries to what the app does, I decided to have an external function that filters and dispatches accordingly. It is not a react component.
import { configureStore } from "@reduxjs/toolkit";
import { addTestToList, addTestActionCreator } from "../Store/PeticionSlice";
import RootReducer from "../Store/RootReuder";
const PruebasToSubmitArray = [];
const store = configureStore({
reducer: RootReducer,
});
const handleTestList = (test, action) => {
const anatomia = "A";
const microbiologia = "M";
function oneBiopsia() {
while (test.key.toString().charAt(0) === anatomia) {
return PruebasToSubmitArray.some(
(pruebaInArray) => pruebaInArray.key.toString().charAt(0) === anatomia
);
}
return false;
}
if (!oneBiopsia() && action === "add") {
switch (test.key.toString().charAt(0)) {
case anatomia:
// console.log("Open pdf for anatomia");
store.dispatch(addTestActionCreator(test));
break;
case microbiologia:
// console.log("Open pdf for micro");
store.dispatch(addTestActionCreator(test));
break;
default:
// console.log("add test to the list, ", test);
store.dispatch(addTestActionCreator(test));
break;
}
} else if (action === "remove") {
// console.log("remove test from the list, ", test);
} else if (oneBiopsia()) {
console.log("Only one biopsia per peticion, ", newState);
}
return null;
};
export default handleTestList;
I added a button on App component and it worked as expected (i showed the updated state), as is right now redux updates the state but the component won't reflect it.
Code SandBox as complete as I can
Upvotes: 7
Views: 19492
Reputation: 427
Very odd behavior in my case.
I did
state = action.payload
and that didn't work.
Once I switched to
state.viewer = action.payload.viewer
everything worked!
Upvotes: 4
Reputation: 42298
You create a store
variable in your index.js
file and pass that store to the react-redux Provider
component. This is the store instance which all react-redux useSelector
and useDispatch
hooks will interact with.
In your HandleTestList.js
file you create a different store
variable. You then dispatch
actions to that store, but those actions won't be reflected in your React app because this isn't the store that your React app uses.
handleTestList
needs to either A) import the same global store
variable. You will want to move this out of index.js
and into store.js
to avoid circular dependencies. or B) accept dispatch
as an argument.
Upvotes: 2