Flashcards Challenge Project (Redux)

I’m happy to have completed this project! It was a great opportunity to practice working with React and Redux. I couldn’t have finished it without the valuable support from the posters in this thread.

Below are the links to my project:

Github Repo

Live Site hosted by Netlify

2 Likes

hi, i like your project and the features you added. was thinking of doing something similar by adding filled states instead of a empty pages with clean state. For a portfolio i think it is valuable to have this project with filled starting state on topics and quizzes as it shows the user how it works. Its easier for a potential recruiter to click than fill input. Will use your project as a reference if I get stuck.

1 Like

Hi all!

Just completed this challenge. I did find it challenging, being new to React/router/Redux but had fun learning too!

Since I wanted to be a bit more modern (react-create is depreciated) I created the project with Vite (npm create vite) and updated the source to match. I also updated the route options to match more modern development pattern.

For those that are struggling to run the built version under a subfolder of their root server, and discovering your project does not work, you need to add the basename property to the options for createBrowserRouter in order for client side routing to work - this is seperate from homepage of package.json and base of vite.config.js, Example is createBrowserRouter(routes, {basename: '/MyFolder' });

The source can be found at https://github.com/FreddeLaszlo/Flashcards

A working version you can play with can be found at https://freddelaszlo.github.io/Flashcards/

Hope this can help people with their own solutions.

Comments/constructive critiicism very much liked!

1 Like

Hello Everyone,
In topicsSlice.js I am not sure why adding a new topic is done by state.topic[id] ? Shouldn’t it be state.topic.topic[id]?

As you are probably aware, there are 3 slices: topics, quizzes, and cards. When you create a slice using createSlice like so:

export const topicsSlice = createSlice({
    name: "topics",
    initialState: {
        topics: {}
    },
    reducers: {
        addTopic: (state, action) => {
            const topicId = action.payload.id;
            state.topics[topicId] = action.payload;
            state.topics[topicId].quizIds = [];
        }
    },
    extraReducers: (builder) => {
        builder
            .addCase(addQuiz, (state, action) => {
                const quizId = action.payload.id;
                const topicId = action.payload.topicId;
                state.topics[topicId].quizIds.push(quizId);
            })
    }
})

the term (state) already refers to the whole slice, which in this case is “topics”. If you call (state) in the “quizzes” slice, it already refers to quizzes.

So since state already refers to topics, using state.topics[topicId] is the way to go.

I hope that clears things up. This might be one of those things where you just have to accept that this is how it is and with enough practice, you’ll understand why it is that way

Here is the code to my Flashcards project:

GitHub: Flashcards

Feedback is welcome

Hi bitace,
Thank you for your reply. Yes I agree with you that you have to look at createSlice as a completely new thing. I think I was treating creatslice like it was just a reducer function. So now I think that i get the name of my slice from name: “topics”, which gives me
state = {
topics
}
Then I get initialState: {topics: {}}. So this makes:
state = {
topics: { topics:{}}
}
So now I can logically get the state.
Also a big concept is that the reducer in createSlice uses the initial state to update the state.
There are alot of concepts here. Thank you I get it now!