我目前正在创建一个React Todo应用程序。所以基本上我有两个组件TodoList和TodoItem
TodoList组件将接收一个由标题组成的对象数组,作为属性,并使用TodoItem组件通过该对象进行映射
在我的TodoItem组件中,用户可以选择编辑或删除该项目。如果用户选择编辑,则会使用文本区域显示带有现有标题的模式信息。但是,我很难实现此功能,因为模态将始终与数组的最后一个元素一起显示。
import React, { Component } from 'react' import TodoItem from './TodoItem' import { connect } from 'react-redux' import { clear_todo } from '../store/actions/todoActions' class Todolist extends Component { clearList = (e) => { e.preventDefault() this.props.clearList(clear_todo()); } handleChange = (index, title) => { this.setState({ [index]: title }) } render() { const { items, editItem } = this.props.todo return ( <ul className="list-group my-5"> <h3 className="text-capitalize text-center"> Todo List </h3> { items.map((item, index) => { const editedTitle = item.title return (<TodoItem key={item.id} title={item.title} id={item.id} editedTitle={editedTitle} onChange={this.handleChange} editItem={editItem} />) }) } <button className="btn btn-danger btn-block text-capitalize mt-5" onClick={this.clearList}> Clear List </button> </ul> ) } } const mapStateToProps = state => { return { todo: state.todo } } const mapDispatchToProps = dispatch => { return { clearList: (clear_todo) => { dispatch(clear_todo) } } } export default connect(mapStateToProps, mapDispatchToProps)(Todolist)
import React, { Component } from 'react' import { connect } from 'react-redux' import { delete_todo, edit_todo, toggle_edit } from '../store/actions/todoActions' import { Button, Modal, ModalHeader, ModalBody, ModalFooter, Form, FormGroup, Input } from 'reactstrap'; import TodoEditItem from './TodoEditItem' class Todoitem extends Component { // constructor(props) { // super(props) // this.state = { // [props.id]: props.title // } // } handleEdit = (id, title) => { this.props.editTodo(edit_todo(id, title)) } toggleEdit = (editItem, title) => { this.props.toggleEdit(toggle_edit(!editItem)) // this.initializeTitle(title) } handleDelete = (id) => { this.props.deleteTodo(delete_todo(id)) } // onChange = (e, id) => { // this.setState({ // [id]: e.target.value // }) // } componentDidMount() { // console.log(this.props) // this.initializeTitle(this.props.title) this.setState({ [this.props.id]: this.props.editedTitle }) console.log(this.state) } render() { // console.log(this.state) let { id, title, editItem, editedTitle, index } = this.props console.log(id) // console.log(index) // let { item } = this.state return ( <div> <li className="list-group-item text-capitlize d-flex justify-content-between my-2"> <h6>{title}</h6> <div className="todo-icon"> <span className="mx-2 text-success" onClick={this.toggleEdit.bind(this, editItem)} > <i className="fas fa-pen"></i> </span> <span className="mx-2 text-danger" onClick={this.handleDelete.bind(this, id)}> <i className="fas fa-trash"></i> </span> </div> <Modal isOpen={editItem}> <ModalHeader>Edit Todo Item</ModalHeader> <ModalBody> <Form> <FormGroup row> <Input type="textarea" name="text" value={this.state ? this.state[id] : ""} onChange={this.props.onChange} /> </FormGroup> </Form> </ModalBody> <ModalFooter> <Button color="primary" onClick={this.handleEdit.bind(this, id, editedTitle)}>Save</Button>{' '} <Button color="secondary" onClick={this.toggleEdit.bind(this, editItem)}> Cancel</Button> </ModalFooter> </Modal> </li> {/* {editItem ? <TodoEditItem title={title} editItem={editItem} /> : ''} */} </div> ) } } const mapDispatchToProps = dispatch => { return { deleteTodo: (delete_todo) => { dispatch(delete_todo) }, editTodo: (edit_todo) => { dispatch(edit_todo) }, toggleEdit: (toggle_edit) => { dispatch(toggle_edit) }, } } export default connect(null, mapDispatchToProps)(Todoitem)
TodoItem的图像
模态图像
从TodoItem的图像中可以看到,我正在尝试编辑“取出垃圾”,但是我的textarea已被预填充为最后一个元素。
您正在使用相同的变量来确定所有TodoItem的打开状态。结果似乎是它仅从数组中获取最后一个值,但实际上每个模态都同时打开,而最后一个是唯一可见的模态。
TodoItem
// editItem here is used to determine the open state of both modals const { items, editItem } = this.props.todo ... { items.map((item, index) => { const editedTitle = item.title return ( <TodoItem key={item.id} title={item.title} id={item.id} editedTitle={editedTitle} onChange={this.handleChange} editItem={editItem} // Same value /> ) }) } ... let { editItem } = this.props <Modal isOpen={editItem}> // All will open and close at the same time
相反,请使用其他标志,或仅按以下方式管理每个孩子的打开状态:
<span className="mx-2 text-success" onClick={() => this.setState({open: true})} > <i className="fas fa-pen"></i> </span> ... <Modal isOpen={this.state.open}>