hello everyone, I cannot figure out what is wrong with my code. I have backtracked my steps and found that somewhere around step 9-10 my code does not show any output. There were no error codes so I went on to finish the rest of the project. I think I have some sort of syntax error but nothing is showing up.
Hello,
Doing a quick scan of your gist I notice that you have
import { useSelector,useDispach } from âreact-reduxâ
which has a syntax error it should be useDispatch
I have also just completed step 10 and created a Gist if you want to compare to see what is different as well
Did this actually solve the problem for you? I am also at step 10 and nothing is rendering. I compared with the code above and found one mistake, which I corrected, but still nothing.
Hi, Iâve been able to complete the project up to line 21. But when I add the line of code
const cardsMatched = useSelector(selectMatchedIDs())
to Score.js, the app crashes with an âUncaught TypeError: state is undefinedâ error. Any clues on what might be going on?
Your useSelector call looks weird to me because youâre passing it a function invocation.
The common usage of useSelector would be to import a state, in your case âselectMatchedIDsâ â which wouldnât be a function â like
import { selectMatchedIDs } from '{yourSlice}';
This state would need to be exported from your slice.
Then youâd just pass that state to useSelector();
Yeah, I figured it out a second ago. Thanks! (I was confusing action creators with selectors)
Iâm having the same problem on step 10⌠I made it all the way through step 9 with no problems but upon completing step 10 nothing is rendering. Since two other people reported this issue and were apparently unable to resolve it Iâm thinking this is⌠yet another bug⌠in⌠yet another important project⌠Frustrating.
Anyone else having this problem?
Can you share your code? You can copy-paste your files here OR you can include a link to github. Perhaps, it may help figure out if there is a mistake in the code OR if the problem lies at Codecademyâs end.
To preserve code formatting in forum posts, see: [How to] Format code in posts
import {createSlice} from â@reduxjs/toolkitâ;
export const CATEGORIES = [âhousingâ, âfoodâ, âtransportationâ, âutilitiesâ, âclothingâ, âhealthcareâ, âpersonalâ, âeducationâ, âentertainmentâ];
const initialState = CATEGORIES.map(category => ({ category: category, amount: 0 }))
const budgetsSlice = createSlice({
name: âbudgetsâ,
initialState: initialState,
reducers: {
editBudget: (state, action) => {
const category = action.payload.category;
const amount = action.payload.amount;
state.find(budget => budget.category === category).amount = amount
}
},
});
const budgetsReducer = (state = initialState, action) => {
switch (action.type) {
case âbudgets/editBudgetâ:
const newBudgets = state.map(budget => {
if (budget.category === action.payload.category) {
return action.payload;
}
return budget;
})
return newBudgets;
default:
return state;
}
}
export const { editBudget } = budgetsSlice.actions;
export const selectBudgets = (state) => state.budgets;
export default budgetsSlice.reducer;
import { createSlice } from â@reduxjs/toolkitâ;
export const CATEGORIES = [âhousingâ, âfoodâ, âtransportationâ, âutilitiesâ, âclothingâ, âhealthcareâ, âpersonalâ, âeducationâ, âentertainmentâ];
const initialState = Object.fromEntries(CATEGORIES.map(category => [category, ]))
const transactionsSlice = createSlice({
name: âtransactionsâ,
initialState: initialState,
reducers: {
addTransaction: (state, action) => {
const category = action.payload.category;
state[category].push(action.payload);
},
deleteTransaction: (state, action) => {
const id = action.payload.id;
const category = action.payload.category;
state[category] = state[category].filter(transaction => transaction.id !== id)
}
},
});
export const selectTransactions = (state) => state.transactions;
export const selectFlattenedTransactions = (state) => Object.values(state.transactions).reduce((a,b) => [âŚa, âŚb], );
const transactionsReducer = (state = initialState, action) => {
let newTransactionsForCategory;
switch (action.type) {
case âtransactions/addTransactionâ:
newTransactionsForCategory = [âŚstate[action.payload.category].slice(), action.payload]
return { âŚstate, [action.payload.category]: newTransactionsForCategory}
case âtransactions/deleteTransactionâ:
const deletedIndex = state[action.payload.category].findIndex(transaction => transaction.id === action.payload.id);
newTransactionsForCategory = state[action.payload.category].filter((item, index) => index !== deletedIndex)
return { âŚstate, [action.payload.category]: newTransactionsForCategory}
default:
return state;
}
}
export { addTransaction, deleteTransaction } = transactionsSlice.action;
export default transactionsSlice.reducer;
import React from âreactâ;
import ReactDOM from âreact-domâ;
import App from â./Appâ;
import { store } from â./app/store.jsâ;
// Add import statement below
import { Provider } from âreact-reduxâ;
ReactDOM.render(
// Implement Provider component with store below
,
document.getElementById(ârootâ)
);
const initialState = [
{id: 0, contents: âProviderâ, visible: true, matched: true},
{id: 1, contents: âProviderâ, visible: true, matched: true},
{id: 2, contents: âselectorâ, visible: true, matched: true},
{id: 3, contents: âselectorâ, visible: true, matched: true},
{id: 4, contents: âuseSelector()â, visible: true, matched: true},
{id: 5, contents: âuseSelector()â, visible: true, matched: true},
{id: 6, contents: âuseDispatch()â, visible: true, matched: true},
{id: 7, contents: âuseDispatch()â, visible: true, matched: true},
{id: 8, contents: âPure Functionâ, visible: true, matched: true},
{id: 9, contents: âPure Functionâ, visible: true, matched: true},
{id: 10, contents: âreact-reduxâ, visible: true, matched: true},
{id: 11, contents: âreact-reduxâ, visible: true, matched: true},
];
export const boardReducer = (state = initialState, action) => {
switch (action.type) {
case âboard/setBoardâ:
let setState = ;
action.payload.forEach((element, index) =>
setState.push({id: index,
contents: element,
visible: false,
matched: false})
);
return setState;
case âboard/flipCardâ:
let flipState = [âŚstate];
const cardID = action.payload;
flipState[cardID] = {âŚstate[cardID], visible:true}
const [index1, index2] = flipState
.filter(card => card.visible)
.map(card => card.id);
if (index2 !== undefined){
const card1 = flipState[index1];
const card2 = flipState[index2];
if (card1.contents === card2.contents) {
flipState[index1] = {âŚcard1, visible: false, matched: true}
flipState[index2] = {âŚcard2, visible: false, matched: true}
}
}
return flipState;
case âboard/resetCardsâ:
return state.map(card => ({âŚcard, visible: false}));
default:
return state;
}
}
const wordPairs = [
âProviderâ, âProviderâ,
âselectorâ, âselectorâ,
âuseSelector()â, âuseSelector()â,
âuseDispatch()â, âuseDispatch()â,
âPure Functionâ, âPure Functionâ,
âreact-reduxâ, âreact-reduxâ,
]
const randomWords = () => {
let words =
let newWordPairs = [âŚwordPairs]
const reps = newWordPairs.length
for (let i=0; i<reps; i++) {
const wordIndex = Math.floor(Math.random()*newWordPairs.length);
words.push(newWordPairs[wordIndex])
newWordPairs.splice(wordIndex, 1)
}
return words;
}
// action creators
export const setBoard = () => {
const words = randomWords()
return {
type: âboard/setBoardâ,
payload: words
}
}
export const flipCard = (id) => {
return {
type: âboard/flipCardâ,
payload: id
}
}
export const resetCards = (indices) => {
return {
type: âboard/resetCardsâ
}
}
// Add selector export statments below
export const selectBoard = state => state.board.map(card => ({id:card, contents:card.contents}));
export const selectVisibleIDs = state =>
state.board
.filter(card => card.visible )
.map(card => card.id);
export const selectMatchedIDs = state =>
state.board
.filter(card => card.matched)
.map(card => card.id);
import React from âreactâ;
import { CardRow } from â./cardRow/CardRow.jsâ;
// Add import statements below
import { useSelector } from âreact-reduxâ;
import { selectBoard } from â./boardSlice.jsâ;
export const Board = () => {
// Add selected data variable and implement below
const currentBoard = useSelector(selectBoard);
const numberOfCards = currentBoard.length;
const columns = 3;
const rows = Math.floor(numberOfCards / columns);
const getRowCards = (row) => {
const rowCards = ;
for (let j = 0; j < columns; j++) {
const cardIndex = row * columns + j;
// Implement selected data below
rowCards.push(currentBoard[cardIndex]);
}
return rowCards;
};
let content = ;
for (let row = 0; row < rows; row++) {
const rowCards = getRowCards(row);
content.push(
);
}
return
};
import React from âreactâ;
// Add import statements below
import { useSelector, useDispatch } from âreact-reduxâ;
import { selectVisibleIDs, flipCard, selectMatchedIDs } from ââŚ/âŚ/boardSlice.jsâ;
let cardLogo = âhttps://static-assets.codecademy.com/Courses/Learn-Redux/matching-game/codecademy_logo.pngâ;
export const Card = ({ id, contents }) => {
// Add selected data and dispatch variables below
visibleIDs = useSelector(selectVisibleIDs);
dispatch = useDispatch();
matchedIDs = useSelector(selectMatchedIDs);
// flip card action
const flipHandler = (id) => {
// Add action dispatch below
dispatch(flipCard(id))
};
let cardStyle = ârestingâ
let click = () => flipHandler(id);
let cardText = (
);
import â./App.cssâ;
import React from âreactâ;
import { Score } from â./features/score/Score.jsâ;
import { Board } from â./features/board/Board.jsâ;
// Add import statements below
import { useDispatch } from âreact-reduxâ;
import { setBoard, resetCards } from â./features/board/boardSlice.jsâ;
const App = () => {
// Add dispatch variable below
const dispatch = useDispatch();
const startGameHandler = () => {
// Add action dispatch below
dispatch(setBoard())
};
const tryAgainHandler = () => {
// Add action dispatch below
dispatch(resetCards())
};
return (
export default App;
import React from âreactâ;
// Add import statement below
import { useSelector } from âreact-reduxâ;
import { selectMatchedIDs } from ââŚ/board/boardSlice.jsâ;
export const Score = () => {
// Add selected data variable below
const cardsMatched = useSelector(selectMatchedIDs);
return (
// implement selected data inside
Unfortunately, you didnât format the code properly ([How to] Format code in posts), so it is difficult to try and follow the code.
One thing that may be of interest:
// You wrote:
export const selectBoard = state => state.board.map(
card => ({id:card, contents:card.contents}));
// Consider changing it to:
export const selectBoard = state => state.board.map(
card => ({id: card.id, contents: card.contents}));
Iâve made the suggested change but the end result is the sameâŚ
Can you copy/paste the instructions for Step 10?
Also, what code did you write just for Step 10 specifically?
By default each Card
component displays the Codecademy logo which means its contents
are not visible. With the visible card IDs now known by each Card
component, each card can show its contents
if it is one of the visible cards or remain hidden otherwise. This logic is handled by the first if
statement in the Card
component definition.
Inside the Card
component definition:
- Remove the
false
in the firstif
statement. Instead, check that theCard
componentâsid
prop is included invisibleIDs
array.
You should now see all the cards in their initialized order.
// 1st if statement
// implement card id array membership check
if (visibleIDs.includes(id) || matchedIDs.includes(id)) {
cardText = contents;
click = () => {};
}
But, this if statement is not present in the code posted by you in the earlier posts.
What is your complete code in the Card.js
file?