gpt4 book ai didi

javascript - React Redux 添加项目到列表会延续到其他创建的列表。

转载 作者:行者123 更新时间:2023-12-03 07:17:02 25 4
gpt4 key购买 nike

我已经为此奋斗了太久,有人可以指出我正确的方向吗?问题:当我创建列表时,我可以更新/删除它。我还可以向其中添加项目并更新/删除这些项目。当我添加另一个列表时,前者的项目会转移到后者,然后我无法编辑这些项目。如果我删除列表并且不刷新浏览器,则项目仍在列表中。我需要一种方法将两者联系在一起,使列表只知道其项目预先感谢您的帮助。

/actions/lists.js

export const CREATE_LIST = 'CREATE_LIST'
export function createList(list) {
return {
type: CREATE_LIST,
id: uuid.v4(),
items: list.items || [],
...list
}
}

export const CONNECT_TO_LIST = 'CONNECT_TO_LIST'
export function connectToList(listId, itemId) {
return {
type: CONNECT_TO_LIST,
listId,
itemId
}
}

export const DISCONNECT_FROM_LIST = 'DISCONNECT_FROM_LIST'
export function disconnectFromList(listId, itemId) {
return {
type: DISCONNECT_FROM_LIST,
listId,
itemId
}
}

/actions/items.js

export const CREATE_ITEM = 'CREATE_ITEM'
export function createItem(item) {
return {
type: CREATE_ITEM,
item: {
id: uuid.v4(),
...item
}
}
}

export const UPDATE_ITEM = 'UPDATE_ITEM'
export function updateItem(updatedItem) {
return {
type: UPDATE_ITEM,
...updatedItem
}
}

/reducers/lists.js

import * as types from '../actions/lists'

const initialState = []

export default function lists(state = initialState, action) {
switch (action.type) {
case types.CREATE_LIST:
return [
...state,
{
id: action.id,
title: action.title,
items: action.items || []
}
]

case types.UPDATE_LIST:
return state.map((list) => {
if(list.id === action.id) {
return Object.assign({}, list, action)
}

return list
})

case types.CONNECT_TO_LIST:
const listId = action.listId
const itemId = action.itemId

return state.map((list) => {
const index = list.items.indexOf(itemId)

if(index >= 0) {
return Object.assign({}, list, {
items: list.items.length > 1 ? list.items.slice(0, index).concat(
list.items.slice(index + 1)): []
})
}
if(list.id === listId) {
return Object.assign({}, list, {
items: [...list.items, itemId]
})
}

return list
})

case types.DISCONNECT_FROM_LIST:
return state.map((list) => {
if(list.id === action.listId) {
return Object.assign({}, list, {
items: list.items.filter((id) => id !== action.itemId)
})
}

return list
})

default:
return state
}
}

/reducers/items.js

import * as types from '../actions/items'

const initialState = []

export default function items(state = initialState, action) {
switch (action.type) {
case types.CREATE_ITEM:
return [ ...state, action.item ]

case types.UPDATE_ITEM:
return state.map((item) => {
if(item.id === action.id) {
return Object.assign({}, item, action)
}

return item
})

case types.DELETE_ITEM:
return state.filter((item) => item.id !== action.id )

default:
return state
}
}

/components/List.jsx

import React from 'react'
import { connect } from 'react-redux'
import { bindActionCreators } from 'redux'
import Items from './Items'
import Editor from './Editor'
import * as listActionCreators from '../actions/lists'
import * as itemActionCreators from '../actions/items'

export default class List extends React.Component {
render() {
const { list, updateList, ...props } = this.props
const listId = list.id

return (
<div {...props}>
<div className="list-header"
onClick={() => props.listActions.updateList({id: listId, isEditing: true})}
>
<div className="list-add-item">
<button onClick={this.addItem.bind(this, listId)}>+</button>
</div>
<Editor
className="list-title"
isEditing={list.isEditing}
value={list.title}
onEdit={title => props.listActions.updateList({id: listId, title, isEditing: false})}
/>
<div className="list-delete">
<button onClick={this.deleteList.bind(this, listId)}>x</button>
</div>
</div>
<Items
items={this.listItems}
onValueClick={id => props.itemActions.updateItem({id, isEditing: true})}
onEdit={(id, text) => props.itemActions.updateItem({id, text, isEditing: false})}
onDelete={itemId => this.deleteItem(listId, itemId)}
/>
</div>
)
}

listItems() {
props.list.items.map(id => state.items[
state.items.findIndex(item => item.id === id)
]).filter(item => item)
}

deleteList(listId, e) {
e.stopPropagation()

this.props.listActions.deleteList(listId)
}

addItem(listId, event) {
event.stopPropagation()

const item = this.props.itemActions.createItem({
text: 'New Shopping Item'
})

this.props.listActions.connectToList(listId, item.id)
}

deleteItem(listId, itemId) {
this.props.listActions.disconnectFromList(listId, itemId)
this.props.itemActions.deleteItem(itemId)
}
}

function mapStateToProps(state) {
return {
lists: state.lists,
items: state.items
}
}

function mapDispatchToProps(dispatch) {
return {
listActions: bindActionCreators(listActionCreators, dispatch),
itemActions: bindActionCreators(itemActionCreators, dispatch)
}
}

export default connect(mapStateToProps, mapDispatchToProps)(List)

/components/List.jsx

import React from 'react'
import List from './List.jsx'

export default ({lists}) => {
return (
<div className="lists">{lists.map((list) =>
<List className="list" key={list.id} list={list} id={list.id} />
)}</div>
)
}

/components/Items.jsx

import React from 'react'
import { connect } from 'react-redux'
import Editor from './Editor'
import Item from './Item'

export default class Items extends React.Component {
render () {
const {items, onEdit, onDelete, onValueClick, isEditing} = this.props

return (
<ul className="items">{items.map(item =>
<Item
className="item"
key={item.id}
id={item.id}
isEditing={item.isEditing}>
<Editor
isEditing={item.isEditing}
value={item.text}
onValueClick={onValueClick.bind(null, item.id)}
onEdit={onEdit.bind(null, item.id)}
onDelete={onDelete.bind(null, item.id)}
/>
</Item>
)}</ul>
)
}
}

export default connect(
state => ({
items: state.items
})
)(Items)

/components/Item.jsx

import React from 'react'

export default class Item extends React.Component {
render() {
const { id, isEditing, ...props } = this.props

return (
<li {...props}>{props.children}</li>
)
}
}

/components/App.jsx

class App extends React.Component {
handleClick = () => {
this.props.dispatch(createList({title: "New Shopping List"}))
}

render() {
const lists = this.props.lists

return (
<div>
<button
className="add-list"
onClick={this.handleClick}>Add Shopping List</button>
<Lists lists={lists}/>
</div>
)
}
}

export default connect(state => ({ lists: state.lists }))(App)

最佳答案

假设这一切都是为了一次对单个数组进行操作,这部分看起来非常可疑:

case types.CREATE_LIST:
return [
...state,
{
id: action.id,
title: action.title,
items: action.items || []
}
]

那个 ...state 正在将现有的数组扩展到您要返回的新数组中,但这听起来并不是您真正想要的行为。我的第一个猜测是,当您创建一个新列表时,您可能只想返回其中的一个新项目,而不是整个旧列表内容加上该新项目。

你的一些其他不可变风格的更新代码看起来也有点复杂。我知道“更新数组中间的东西”并不总是那么容易处理。您可能想看看this SO post on updating immutable data ,其中列出了几种实现它的方法。我还有一个链接存储库,用于对 Redux 相关的库进行编目,它有一个列表 immutable data management libraries这可能会让你的事情变得更容易。

关于javascript - React Redux 添加项目到列表会延续到其他创建的列表。,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36381202/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com