Как в React JS передать значения через map компоненту
Столкнулся с проблемой что при передаче value в TodoList.jsx возникает ошибка :
Cannot read properties of undefined (reading 'map')
TypeError: Cannot read properties of undefined (reading 'map')
*После некоторых изменений в коде выдают еще и это :Too many re-renders. React limits the number of renders to prevent an infinite loop.
Я передаю значение cats по такому пути App.js -> TodoList.jsx -> ToDoItems.jsx
App.js :
import React, {useEffect, useState} from 'react';
import TodoList from "./components/TodoList";
import './App.css';
import PostForm from './components/PostForm';
import TodoService from './components/API/ToDoService';
import Loader from './components/UI/Loader/Loader';
import MyModal from './components/UI/MyModal/MyModal';
import MyButton from './components/UI/button/MyButton';
function App(){
const [post, setPosts] = useState([]);
const [cats, setCats] = useState([]);
const [isPostsLoading, setIsPostsLoading] = useState(false);
const [modal, setModal] = useState(false);
useEffect(() => {
fetchList()
}, [])
async function fetchList() {
setIsPostsLoading(true);
const response_data_todo = await TodoService.getTodo();
const response_data_cat = await TodoService.getCategory();
setPosts(response_data_todo);
setCats(response_data_cat);
setIsPostsLoading(false);
}
return (
<div>
<MyButton style={{ marginTop: 30, marginbottom: 30, marginleft:300,marginright:300 }} onClick={() => setModal(true)}>
Создать Пост
</MyButton>
<MyModal visible={modal} setVisible={setModal} >
<PostForm value={cats} option={cats} defaultValue="Категория" />
</MyModal>
{isPostsLoading
? <div style={{display:'flex', justifyContent:'center', marginTop:50}}><Loader/></div>
:<TodoList post={post} value={cats} option={cats} title='Список Постов ' />
}
</div>
)
}
export default App;
Todolist.jsx:
import React from "react";
import TodoItems from "./TodoItems";
const TodoList = ({ post, title , value}) => {
return (
<div className="List">
<h1 style={{ textAlign: "center", }}>{title}</h1>
{ post.map((post) =>
<TodoItems post={post} key={post.id} value={value} />
)}
</div>
)
}
export default TodoList;
ToDoItems.jsx:
import React, { useState } from 'react';
import MyButton from './UI/button/MyButton';
import TodoService from './API/ToDoService';
import MyModal from './UI/MyModal/MyModal';
import PostForm from './PostForm';
const ToDoItem = (props,value) => {
const [modalupdate, setModalUpdate] = useState(false);
return (
<div className = "items">
<strong>{props.post.title}</strong>
<div>{ props.post.category}</div>
<div>
{props.post.description}
<a style={{color:'green'} } >{props.post.time_create}</a>
</div>
<div>
<MyButton onClick = {() => setModalUpdate(true)}>Изменить</MyButton>
</div>
<MyModal>
<PostForm value={value} options={value} idPost={props.post.id} defaultValue="Категория"/>
</MyModal>
<div>
<button type="submit" onClick={() => { TodoService.deleteTodo(props.post.id); document.location.reload(); }}>Удалить</button>
</div>
</div>
)
}
export default ToDoItem;
Я хочу реализовать изменение(PUT запрос) TodoItems через модальное окно, value содержит id и name категорий, id и name нужны для выпадающего списка в котором выбирается категория.map должна передавать value списком то есть по сути для каждого Todoitems будет свой список категории
Ответы (1 шт):
Проблема в вашем коде возникает из-за неправильного использования пропсов в компоненте ToDoItems. Вы передаете value в компонент ToDoItems как пропс, но затем извлекаете его, как если бы это был отдельный аргумент. Вам нужно изменить компонент ToDoItems следующим образом:
Вместо:
const ToDoItem = (props,value) => {
Используйте:
const ToDoItem = ({ post, value }) => {
После этого изменения вы сможете обращаться к value внутри компонента ToDoItems, как value. Также я заметил, что в компоненте ToDoItems вы используете MyModal, но не передаете ему свойства visible и setVisible. Вам нужно добавить эти свойства для правильной работы модального окна:
<MyModal visible={modalupdate} setVisible={setModalUpdate}>
Теперь ваш код должен работать без ошибок и компонент ToDoItems должен получать список категорий.