1

我正在学习 React/Redux,并试图修改一个教程项目,使其更像我曾经在 Angular 中工作过的应用程序。我在使用 array.map 生成表行的功能组件中有一个对象列表。我想通过在给定数据行的显示和编辑模式之间切换来编辑每一行。我可以将逻辑放入其中以显示每种模式的正确元素/组件,但尚未使标记正常运行。我有一个带有切换模式的 onClick 事件处理程序的图标。

 let oldCourse = { isEditing: false };
    
function onEditClick(course) {
    debugger;
    course.isEditing = true;
    oldCourse = course;
}

包含图标的单元格是我正在尝试做的事情类型的一个示例。我意识到我可以在单个图标元素中使用三元表达式来做同样的事情,但这是一个简单的第一次剪辑。

<td>
    {course.isEditing && (
        <FontAwesomeIcon
            icon={faTrashRestore}
            size='md'
            cursor='pointer'
            onClick={() => onCancelClick(course)}
        />
    )}
    {!course.isEditing && (
        <span onClick={() => onEditClick(course)}>
            <FontAwesomeIcon icon={faEdit} size='md' cursor='pointer' />
        </span>
    )}
</td>

由于与 Angular 不同,React/Redux 的数据绑定是单向的,所以我还没有弄清楚机制。我想要发生的是让单元格内容按照描述进行切换,但想要关于如何完成此操作的建议。

这是组件的完整来源。

import React, { useState } from "react";
import { connect } from "react-redux";
import PropTypes from "prop-types";
import { Link } from "react-router-dom";
import "../../fontawesome";
import { faTrashAlt, faTrashRestore, faEdit, faEye, faSave } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";

export function CourseList({ courses, onDeleteClick }) {
    const [course, setCourse] = useState({ isEditing: false });
    const [oldCourse, setOldCourse] = useState(course);

    function onEditClick(course) {
        debugger;
        const updatedCourse = { ...course, isEditing: true };
        setCourse(updatedCourse);
        setOldCourse(updatedCourse);
    }

    function onCancelClick() {
        setCourse({ ...oldCourse, isEditing: false });
    }

    return (
        <table className='table'>
            <thead>
                <tr>
                    <th />
                    <th>Title</th>
                    <th>Author</th>
                    <th>Category</th>
                    <th />
                </tr>
            </thead>
            <tbody>
                {courses.map(course => (
                    <tr key={course.id}>
                        <td>
                            <a href={"http://pluralsight.com/courses/" + course.slug}>
                                <FontAwesomeIcon icon={faEye} size='md' cursor='pointer' />
                            </a>
                        </td>
                        <td>
                            <Link to={"/course/" + course.slug}>{course.title}</Link>
                        </td>
                        <td>{course.authorName}</td>
                        <td>{course.category}</td>
                        <td>
                            <table>
                                <tr>
                                    <td>
                                        {course.isEditing && (
                                            <span onClick={() => onCancelClick()}>
                                                <FontAwesomeIcon
                                                    icon={faTrashRestore}
                                                    size='md'
                                                    cursor='pointer'
                                                />
                                            </span>
                                        )}
                                        {!course.isEditing && (
                                            <span onClick={() => onEditClick(course)}>
                                                <FontAwesomeIcon icon={faEdit} size='md' cursor='pointer' />
                                            </span>
                                        )}
                                    </td>
                                    <td>
                                        {!course.isEditing && (
                                            <span onClick={() => onDeleteClick(course)}>
                                                <FontAwesomeIcon
                                                    icon={faTrashAlt}
                                                    size='md'
                                                    cursor='pointer'
                                                />
                                            </span>
                                        )}
                                        {course.isEditing && (
                                            <span>
                                                <FontAwesomeIcon icon={faSave} size='md' cursor='pointer' />
                                            </span>
                                        )}
                                    </td>
                                </tr>
                            </table>
                        </td>
                    </tr>
                ))}
            </tbody>
        </table>
    );
}

CourseList.propTypes = {
    courses: PropTypes.array.isRequired,
    onDeleteClick: PropTypes.func.isRequired,
};

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

export default connect(mapStateToProps)(CourseList);

谢谢,迈克

4

1 回答 1

0

您可以使用它useState来记住应用程序中所需的状态的某些部分。查看以下示例:

const [course, setCourse] = useState({ isEditing: false })
const [oldCourse, setOldCourse] = useState(course);
    
function onEditClick(course) {
    const updatedCourse = {...course, isEditing: true};
    setCourse(updatedCourse)
    setOldCourse(updatedCourse);
}

<td>
    {course.isEditing && (
        <FontAwesomeIcon
            icon={faTrashRestore}
            size='md'
            cursor='pointer'
            onClick={() => onCancelClick(course)}
        />
    )}
    {!course.isEditing && (
        <span onClick={() => onEditClick(course)}>
            <FontAwesomeIcon icon={faEdit} size='md' cursor='pointer' />
        </span>
    )}
</td>

在多个课程的背景下:

export function CourseList({ courses, onDeleteClick }) {
  const [editingStatusByCourseId, setEditingStatus] = useState({});
  const [courseToUpdate, setCourseToUpdate] = useState({});

  function onEditClick(course) {
    setEditingStatus({ ...editingStatusByCourseId, [course.id]: true });
    setCourseToUpdate(course);
  }

  function onCancelClick(course) {
    setEditingStatus({ ...editingStatusByCourseId, [course.id]: false });
    setCourseToUpdate({});
  }

  function onSaveClick(course){
    // call your redux action to save/update the course.
  }

  return (
    <table className="table">
      <thead>
        <tr>
          <th />
          <th>Title</th>
          <th>Author</th>
          <th>Category</th>
          <th />
        </tr>
      </thead>
      <tbody>
        {courses.map((course) => {
          const isInEditMode = editingStatusByCourseId[course.id] === true;

          return (
            <tr key={course.id}>
              <td>
                <a href={"http://pluralsight.com/courses/" + course.slug}>
                  <FontAwesomeIcon icon={"faEye"} size="md" cursor="pointer" />
                </a>
              </td>
              <td>
                <Link to={"/course/" + course.slug}>{course.title}</Link>
              </td>
              <td>{course.authorName}</td>
              <td>{course.category}</td>
              <td>
                <table>
                  <tr>
                    <td>
                      {isInEditMode && (
                        <span onClick={() => onCancelClick(course)}>
                          <FontAwesomeIcon
                            icon={"faTrashRestore"}
                            size="md"
                            cursor="pointer"
                          />
                        </span>
                      )}
                      {!isInEditMode && (
                        <span onClick={() => onEditClick(course)}>
                          <FontAwesomeIcon
                            icon={"faEdit"}
                            size="md"
                            cursor="pointer"
                          />
                        </span>
                      )}
                    </td>
                    <td>
                      {!isInEditMode && (
                        <span onClick={() => onDeleteClick(course)}>
                          <FontAwesomeIcon
                            icon={"faTrashAlt"}
                            size="md"
                            cursor="pointer"
                          />
                        </span>
                      )}
                      {isInEditMode && (
                        <span onClick={() => onSaveClick(course)}>
                          <FontAwesomeIcon
                            icon={"faSave"}
                            size="md"
                            cursor="pointer"
                          />
                        </span>
                      )}
                    </td>
                  </tr>
                </table>
              </td>
            </tr>
          );
        })}
      </tbody>
    </table>
  );
}
于 2021-04-28T11:51:02.917 回答