Как в React JS передать значения через map компоненту

Рейтинг: 0Ответов: 1Опубликовано: 11.04.2023

Столкнулся с проблемой что при передаче 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 будет свой список категории

Ответы

▲ 2Принят

Проблема в вашем коде возникает из-за неправильного использования пропсов в компоненте 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 должен получать список категорий.