Topic can’t render onto the screen after adding in the form and submitting.
This is my NewTopicForm.js
import React, { useState } from "react";
import { useHistory } from "react-router-dom";
import { v4 as uuidv4 } from "uuid";
import ROUTES from "../app/routes";
import { ALL_ICONS } from "../data/icons";
import { addTopic } from "../features/topics/newFile";
import { useDispatch } from "react-redux";
export default function NewTopicForm() {
const [name, setName] = useState("");
const [icon, setIcon] = useState("");
const history = useHistory();
const dispatch = useDispatch();
const handleSubmit = (e) => {
e.preventDefault();
if (name.length === 0) {
return;
}
// dispatch your add topic action here
dispatch(addTopic({name: topics, id: uuidv4(), icon: icon}));
history.push(ROUTES.topicsRoute());
};
return (
<section>
<form onSubmit={handleSubmit}>
<h1 className="center">Create a new topic</h1>
<div className="form-section">
<input
id="topic-name"
type="text"
value={name}
onChange={(e) => setName(e.currentTarget.value)}
placeholder="Topic Name"
/>
<select
onChange={(e) => setIcon(e.currentTarget.value)}
required
defaultValue="default"
>
<option value="default" disabled hidden>
Choose an icon
</option>
{ALL_ICONS.map(({ name, url }) => (
<option key={url} value={url}>
{name}
</option>
))}
</select>
</div>
<button className="center">Add Topic</button>
</form>
</section>
);
}
My new file/ topic slice
import { createSlice } from '@reduxjs/toolkit';
const options = {
name: 'topics',
initialState: {
topics: {}
},
reducers: {
addTopic: (state, action) => {
const { id, name, icon } = action.payload;
state.topics[id] = {
id: id,
name: name,
icon: icon,
quizIds: []
}
},
addQuizId: (state, action) => {
const { quizId, topicId } = action.payload;
state.topics[topicId].quizIds.push(quizId);
}
}
};
export const selectTopic = (state) => state.topics.topics;
export const { addTopic, addQuizId } = newFile.actions;
export default newFile.reducer;
did you manage to solve the problem?
i also can’t see any added topic, tho i cant find any problem with my code.
store.js
import { configureStore } from "@reduxjs/toolkit";
import topicsReducer from '../features/topics/topicsSlice';
export default configureStore({
reducer: {
topics: topicsReducer
},
});
topicsSlice.js
import {createSlice} from '@reduxjs/toolkit';
export const topicsSlice = createSlice({
name: 'topics',
initialState: {
topics:{}
},
reducers:{
addTopic: (state, action) => {
const { id, name, icon } = action.payload;
state.topics[id] = {
id: id,
name: name,
icon: icon,
quizIds =[]
}
}
}
})
export const selectTopic = state => state.topics.topics;
export const {addTopic} = topicsSlice.actions;
export default topicsSlice.reducer;
Topics.js
import React from "react";
import NewTopicForm from "../../components/NewTopicForm";
import { Link } from "react-router-dom";
import ROUTES from "../../app/routes";
import {selectTopic} from './topicsSlice';
import {useSelector} from 'react-redux';
export default function Topics() {
const topics = useSelector(selectTopic)
return (
<section className="center">
<h1>Topics</h1>
<ul className="topics-list">
{Object.values(topics).map((topic) => (
<li className="topic" key={topic.id}>
<Link to={ROUTES.topicRoute(topic.id)} className="topic-link">
<div className="topic-container">
<img src={topic.icon} alt="" />
<div className="text-content">
<h2>{topic.name}</h2>
<p>{topic.quizIds.length} Quizzes</p>
</div>
</div>
</Link>
</li>
))}
</ul>
<Link
to={ROUTES.newTopicRoute()}
className="button create-new-topic-button"
>
Create New Topic
</Link>
</section>
);
}
NewTopicForm.js
import React, { useState } from "react";
import { useHistory } from "react-router-dom";
import { v4 as uuidv4 } from "uuid";
import ROUTES from "../app/routes";
import { ALL_ICONS } from "../data/icons";
import {addTopic} from '../features/topics/topicsSlice';
import {useDispatch} from 'react-redux';
export default function NewTopicForm() {
const [name, setName] = useState("");
const [icon, setIcon] = useState("");
const history = useHistory();
const dispatch = useDispatch();
const handleSubmit = (e) => {
e.preventDefault();
if (name.length === 0) {
return;
}
// dispatch your add topic action here
dispatch(addTopic({
name: name,
id: uuidv4(),
icon: icon
}))
history.push(ROUTES.topicsRoute());
};
return (
<section>
<form onSubmit={handleSubmit}>
<h1 className="center">Create a new topic</h1>
<div className="form-section">
<input
id="topic-name"
type="text"
value={name}
onChange={(e) => setName(e.currentTarget.value)}
placeholder="Topic Name"
/>
<select
onChange={(e) => setIcon(e.currentTarget.value)}
required
defaultValue="default"
>
<option value="default" disabled hidden>
Choose an icon
</option>
{ALL_ICONS.map(({ name, url }) => (
<option key={url} value={url}>
{name}
</option>
))}
</select>
</div>
<button className="center">Add Topic</button>
</form>
</section>
);
}
can someone check it?