javascript - map 在 React 中的第一次迭代后停止迭代

标签 javascript reactjs redux ecmascript-6 redux-thunk

我的组件应该在安装组件时检索类(class)数据。我遇到的问题是,无论我使用类(class) ID 还是类(class)标题​​作为键,我都会收到以下错误:

index.js:1 Warning: Each child in a list should have a unique "key" prop.

我查看了 Stack Overflow 上的 React 文档,并尝试了不同的方法来让它工作。我能让它部分工作的唯一方法是添加一个索引作为 map 的参数。当我使用这种方法时,我遇到了另一个问题,即它在第一次迭代后停止,即使有 10 个项目。我该如何解决这个问题?

这是我的代码:

CoursesPage.js

import React from 'react';
import { connect } from 'react-redux';
import * as courseActions from '../../redux/actions/courseActions';
import PropTypes from 'prop-types';
import { bindActionCreators } from 'redux';

class CoursesPage extends React.Component {

    componentDidMount() {
        this.props.actions.loadCourses().catch(error => {
            alert("Loading courses failed" + error);
        });

    }


    render() {
        return (
            <>
                <h2>Courses</h2>

                

{this.props.courses.map((course, index) => (

                    <div key={course[index].title}>{course[index].title}</div>


                ))}
            </>
        );
    }
}

CoursesPage.propTypes = {
    courses: PropTypes.array.isRequired,
    actions: PropTypes.object.isRequired
}

function mapStateToProps(state) {
    return {
        courses: state.courses
    }

}

function mapDispatchToProps(dispatch) {

    return {
        actions: bindActionCreators(courseActions, dispatch)
    }

}

export default connect(mapStateToProps, mapDispatchToProps)(CoursesPage);

我的模拟数据:

const courses = [
    {
        id: 1,
        title: "Securing React Apps with Auth0",
        slug: "react-auth0-authentication-security",
        authorId: 1,
        category: "JavaScript"
    },
    {
        id: 2,
        title: "React: The Big Picture",
        slug: "react-big-picture",
        authorId: 1,
        category: "JavaScript"
    },
    {
        id: 3,
        title: "Creating Reusable React Components",
        slug: "react-creating-reusable-components",
        authorId: 1,
        category: "JavaScript"
    },
    {
        id: 4,
        title: "Building a JavaScript Development Environment",
        slug: "javascript-development-environment",
        authorId: 1,
        category: "JavaScript"
    },
    {
        id: 5,
        title: "Building Applications with React and Redux",
        slug: "react-redux-react-router-es6",
        authorId: 1,
        category: "JavaScript"
    },
    {
        id: 6,
        title: "Building Applications in React and Flux",
        slug: "react-flux-building-applications",
        authorId: 1,
        category: "JavaScript"
    },
    {
        id: 7,
        title: "Clean Code: Writing Code for Humans",
        slug: "writing-clean-code-humans",
        authorId: 1,
        category: "Software Practices"
    },
    {
        id: 8,
        title: "Architecture Applications for the Real World",
        slug: "architecting-applications-dotnet",
        authorId: 1,
        category: "Software Architecture"
    },
    {
        id: 9,
        title: "Becoming an Outlier: Reprogramming the Developer Mind",
        slug: "career-reboot-for-developer-mind",
        authorId: 1,
        category: "Career"
    },
    {
        id: 10,
        title: "Web Component Fundamentals",
        slug: "web-components-shadow-dom",
        authorId: 1,
        category: "HTML5"
    }
];

const authors = [
    { id: 1, name: "Cory House" },
    { id: 2, name: "Scott Allen" },
    { id: 3, name: "Dan Wahlin" }
];

const newCourse = {
    id: null,
    title: "",
    authorId: null,
    category: ""
};

module.exports = {
    newCourse,
    courses,
    authors
};

编辑: 我正在使用 Redux Thunk。

这是我的actionType.js 文件:

export const CREATE_COURSE = "CREATE_COURSE";
export const LOAD_COURSES_SUCCESS = "LOAD_COURSES_SUCCESS";

这是我的CourseActions.js 文件:

import * as types from './actionTypes';
import * as courseApi from "../../api/courseApi";

export function createCourse(course) {
    return { type: types.CREATE_COURSE, course };
}

export function loadCourseSuccess(courses) {
    return { type: types.LOAD_COURSES_SUCCESS, courses };
}

export function loadCourses() {
    return function (dispatch) {
        return courseApi.getCourses().then(courses => {
            dispatch(loadCourseSuccess(courses));
        }).catch(error => {
            throw error;
        })

    }
}

这是我的 courseReducer.js 文件:

import * as types from '../actions/actionTypes';

export default function courseReducer(state = [], action) {

    switch (action.type) {
        case types.CREATE_COURSE:
            return [...state, { ...action.course }];

        case types.LOAD_COURSES_SUCCESS:
            return [...state, { ...action.courses }];

        default:
            return state;
    }
}

如有任何帮助,我们将不胜感激。

谢谢。

附言我知道您应该使用 Id 作为 key 。但目前必须采用的方法是使用类(class)标题作为 key 。

最佳答案

通过您的修改,我认为我们可以更有效地帮助您。对于 future ,发布一个您的代码示例在 https://codesandbox.io/ 上不起作用将是有益的

另外,为了在调试时帮助自己,将 react 组件与 redux 的使用隔离开来。这将允许您确保您的 React 组件在给定数据时呈现,然后专注于让 redux 为您提供您的 React 组件所拥有的数据。

您可以通过首先在您的 React 组件中定义模拟数据,然后将该模拟数据移动到您的 reducer,最后用实时 API 调用替换模拟数据来做到这一点。

关于代码:

你有两个问题:第一个是你想索引数组 courses但由于打字错误,您实际上是在对象中使用属性访问器 course

key={course[index].title}

正如您的问题所述,您必须使用标题作为键,只需将 div 更改为:

<div key={course.title}>{course.title}</div>并且您的代码应该按预期工作。

一旦你解决了这个问题,然后使用 Redux 重新启用从你的 API 调用加载数据,你就可以解决 Redux 的问题。

看看你的 reducer ,你有一个明显的错误,并且根据你的用例,一个潜在的错误:

case types.LOAD_COURSES_SUCCESS:
            return [...state, { ...action.courses }];

action.courses是一个数组,代码正在创建一个新数组,其中包含前一个数组的所有元素 state并添加一个新对象,其中包含解构 array.courses 的内容数组。

这样做实际上是将单个对象附加到您的数组,并且该对象由类(class)数组中的元素组成。项目索引成为键,项目本身就是值。

您可以在此处可视化它:https://codesandbox.io/s/divine-pond-nr3j8

相反,你想要

return [...state, ...action.courses];

第二个潜在错误是您实际上是在附加类(class) api 的结果。对于后续加载类(class)的调用,您将复制数据。这可能是您想要的,但我假设这不是您想要的。

因此,您的 LOAD_COURSES_SUCCESS case 应该重写为:

return [...action.courses];

关于javascript - map 在 React 中的第一次迭代后停止迭代,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63609452/

相关文章:

javascript - Durandal 路由器未激活

javascript - 如何在 redux 中调度函数?

reactjs - 操作可能没有未定义的 "type"属性。你是否拼错了一个常量?

javascript - JS : calculate range numbers like [-10, 10]使用百分比并根据百分比值获取数字

javascript - 自定义javascript提示和确认框

javascript - 某些 HTML 字符实体仅在 Firefox 中很大

javascript - 未捕获的语法错误 : Unexpected token < reactjs react-pdf

javascript - 增加 Action 创建器中的变量

javascript - 来自父级组件的 JSX 作为字符串

reactjs - 如何在 redux 的 DIspatch 中使用回调?