我刚开始学习react和redux,当时我正在设计一个待办事项列表应用程序(具有两层嵌套),遇到了一个问题。 所以这就是我的输出在屏幕上的样子,如图所示,座右铭是当我单击任何'x'时,相应的元素将被删除,状态将更新,并且UI会重新呈现。 红色框中的数据是(就像上面的孩子一样),即:“工作”,“素描”,“健身房”,“晚餐”是父级元素,红色框中的数据是下一级数据。
当我删除work / sketch / gym / dinner时,它们可以正常工作,但是我尝试删除任何嵌套元素,但它不起作用。是因为我要删除嵌套数据吗?
这是我的代码:谁能告诉我我在做什么错
src / App.js:
import React from 'react';
import './App.css';
import Wrapper from './components/wrapper'
import store from './redux/store'
import { Provider } from 'react-redux';
class App extends React.Component{
render() {
return (
<Provider store={store} >
<div className="App">
<Wrapper />
</div>
</Provider>
)
}
}
export default App;
src / components / childComponent.js
import React, { Fragment } from 'react';
import {addChildEelem, deleteChildElem} from '../redux/actions';
import {connect} from 'react-redux';
class ChildComponent extends React.Component{
render() {
if(this.props.displayChild) {
return (
<Fragment>
<input id="second-input"/>
<button id="second-button">Add</button>
<div className="second_level_cards">
{
this.props.data.map((elem) => {
return (
<div className="second_level_card">
<li id={elem.list_id}>
{elem.list_content}
</li>
<span
className="close"
onClick={this.props.deleteChildEelem_}>
X
</span>
</div>
)
})
}
</div>
</Fragment>
)
}
else {
return (
<div></div>
)
}
}
}
const mapStateToProps = (state) => {
return {
fullData_ : state
}
}
const mapDispatchToProps = (dispatch) => {
return {
addChildEelem_ : (e) => dispatch(addChildEelem(e)),
deleteChildEelem_ : (e) => dispatch(deleteChildElem(e))
}
}
export default connect(mapStateToProps, mapDispatchToProps)(ChildComponent);
src / component / parentComponent.js
import React, { Fragment } from 'react';
import {connect} from 'react-redux';
import '../App.css'
import ChildComponent from './childComponent'
import {addFirstLevelElem, deleteFirstLevelElem, addChildEelem, deleteChildElem} from '../redux/actions'
class parentElement extends React.Component {
constructor(props){
super(props);
this.state = {displayChild: true}
}
displaychildHandler = () => {
this.setState({
displayChild: !this.state.displayChild
})
}
render() {
const {displayChild} = this.state;
return (
<div>
<div className="first_level_card">
<div className="parent">
<li className="flcc" id={this.props.data.list_id} onClick={this.displaychildHandler}>
{this.props.data.list_content}
</li>
<span
className="flcc close"
onClick={this.props.deleteFirstLevelElem_}
>X</span>
</div>
<div className="child">
<ChildComponent
displayChild={displayChild}
data={this.props.data.list_children}
/>
{/* <input id="second-input"/>
<button id="second-button">Add</button>
<div className="second_level_cards">
{
this.props.data.list_children.map((elem) => {
return (
<div className="second_level_card">
<li id={elem.list_id}>
{elem.list_content}
</li>
<span
className="close"
onClick={this.props.deleteChildEelem_}>
X
</span>
</div>
)
})
}
</div>
*/}
</div>
</div>
</div>
)
}
}
const mapStateToProps = (state) => {
return {
fullUsers : state
}
}
const mapDispatchToProps = (dispatch) => {
return {
addFirstLevelElem_: (e) => dispatch(addFirstLevelElem(e)),
deleteFirstLevelElem_: (e) => dispatch(deleteFirstLevelElem(e)),
addChildEelem_ : (e) => dispatch(addChildEelem(e)),
deleteChildEelem_ : (e) => dispatch(deleteChildElem(e))
}
}
export default connect(mapStateToProps, mapDispatchToProps)(parentElement);
src / component / wrapper.js:
import React, { Fragment } from 'react';
import ParentElement from './parentComponent'
import {addFirstLevelElem, deleteFirstLevelElem, addChildEelem, deleteChildElem} from '../redux/actions'
import {connect} from 'react-redux';
class Wrapper extends React.Component {
render() {
return(
<Fragment>
<input id='input' />
<button id='button'>Add</button>
{
this.props.fullData_.map(
(elem) => {
return (
<ParentElement
data={elem}
/>
)
}
)
}
</Fragment>
)
}
}
const mapStateToProps = (state) => {
return {
fullData_ : state
}
}
export default connect(mapStateToProps)(Wrapper);
src / redux / actions.js:
import {ADD_FIRST_LEVEL_ELEM,
DELETE_FIRST_LEVEL_ELEM,
ADD_CHILD_ELEM,
DELETE_CHILD_ELEM
} from './constTypes';
export const addFirstLevelElem = (data) => {
return {
type: ADD_FIRST_LEVEL_ELEM,
payload: data
}
}
export const deleteFirstLevelElem = (data) => {
return {
type: DELETE_FIRST_LEVEL_ELEM,
payload: data
}
}
export const addChildEelem = (data) => {
return {
type: ADD_CHILD_ELEM,
payload: data
}
}
export const deleteChildElem = (data) => {
return {
type: DELETE_CHILD_ELEM,
payload: data
}
}
src / redux / constTypes.js:
export const ADD_FIRST_LEVEL_ELEM = "ADD_FIRST_LEVEL_ELEM";
export const DELETE_FIRST_LEVEL_ELEM = "DELETE_FIRST_LEVEL_ELEM";
export const ADD_CHILD_ELEM = "ADD_CHILD_ELEM";
export const DELETE_CHILD_ELEM = "DELETE_CHILD_ELEM";
src / redux / reducer.js:
import {
ADD_FIRST_LEVEL_ELEM,
DELETE_FIRST_LEVEL_ELEM,
ADD_CHILD_ELEM,
DELETE_CHILD_ELEM
} from './constTypes';
import fullData from '../data';
const initialState = fullData;
let constReturnValue;
const addFirstLevelElement = (e, stateList) => {
console.log(e, stateList);
}
const deleteFirstLevelElement = (e, stateList) => {
let deleteElemId = e.target.previousElementSibling.id;
let newList = stateList.filter((elem) => elem.list_id != deleteElemId )
return newList;
}
const addChildElement = (e, stateList) => {
console.log(e, stateList);
}
const deleteChildElement = (e, stateList) => {
let elemToBeDeletedId = e.target.previousElementSibling.id;
let parentHierarchy = e.target.previousElementSibling.id[0];
let parentId = `first_card_${parentHierarchy}`;
let newChildList, newList = stateList;
for(let i=0; i<newList.length; i++) {
if(newList[i].list_id == parentId) {
newChildList = newList[i].list_children.filter((elem) => elem.list_id != elemToBeDeletedId)
newList[i].list_children = newChildList
}
}
return newList;
}
export const reducer = (state=initialState, action) => {
switch(action.type) {
case ADD_FIRST_LEVEL_ELEM:
constReturnValue = addFirstLevelElement(action.payload, state);
return constReturnValue
case DELETE_FIRST_LEVEL_ELEM:
constReturnValue = deleteFirstLevelElement(action.payload, state);
return constReturnValue;
case ADD_CHILD_ELEM:
constReturnValue = addChildElement(action.payload, state);
return constReturnValue;
case DELETE_CHILD_ELEM:
constReturnValue = deleteChildElement(action.payload, state);
return constReturnValue;
default: return state;
}
}
src / redux / store.js
import { createStore} from 'redux';
import {reducer} from './reducer'
const store = createStore(reducer);
export default store;
src / data.js:
const ListData = [
{
list_id: "first_card_1",
list_content: "Work",
list_state: "pending",
list_children:
[
{
list_id: "1_card_child_1",
list_content: "Have breakfast",
list_state: "pending",
},
{
list_id: "1_card_child_2",
list_content: "Keep wallet and ID card",
list_state: "pending"
},
{
list_id: "1_card_child_3",
list_content: "Book a cab",
list_state: "pending"
},
{
list_id: "1_card_child_4",
list_content: "Reached office",
list_state: "pending"
}
]
},
{
list_id: "first_card_2",
list_content: "Sketch",
list_state: "pending",
list_children:
[
{
list_id: "2_card_child_1",
list_content: "Charge ipad and pencil",
list_state: "pending"
},
{
list_id: "2_card_child_2",
list_content: "List down ideas meanwhile",
list_state: "pending"
},
{
list_id: "2_card_child_3",
list_content: "start execution",
list_state: "pending"
},
{
list_id: "2_card_child_4",
list_content: "Mark Done",
list_state: "pending"
},
]
},
{
list_id: "first_card_3",
list_content: "Gym",
list_state: "pending",
list_children:
[
{
list_id: "3_card_child_1",
list_content: "Keep extra clothes",
list_state: "pending"
}
]
},
{
list_id: "first_card_4",
list_content: "Dinner",
list_state: "pending",
list_children:
[
{
list_id: "4_card_child_1",
list_content: "Buy groceries",
list_state: "pending"
},
{
list_id: "4_card_child_2",
list_content: "Call Cook",
list_state: "pending"
},
]
},
]
export default ListData;