首页 > 解决方案 > 从 Firebase 中删除组件后更新组件

问题描述

请告诉我在删除其中一项后如何正确更新 PathItems 组件。组件本身从列表中消失了,但它的描述仍然存在(参见随附的屏幕截图)。

路径项组件:

import Item from "./PathItem";
import FullDecript from "./PathFullDescription";

import { firestoreConnect } from 'react-redux-firebase';
import { compose } from "redux";
import { connect } from "react-redux"
import {Col, Row} from "react-bootstrap";

const PathItems = (props) => {
    const divStyle = {
        overflowY: 'scroll',
        height: '85vh'
    };

    const [info, setInfo] = useState(null);

    return (
        <React.Fragment>
            <Row>
                <Col className="pl-0 border-right border-dark" style={divStyle}>
                    {props.pathDescription && props.pathDescription.map(item => (
                        <Item
                            key={item.id}
                            item={item}
                            onInfoChange={setInfo}
                        />
                    ))}
                </Col>
                <Col>
                    {info !== null ? <FullDecript {...info}/> : null}
                </Col>
            </Row>
        </React.Fragment>
    )
}

const mapStateToProps = (state) => {
    return {
        pathDescription: state.firestore.ordered.pathDescription
    }
}

export default compose(
    firestoreConnect(()=> ['pathDescription']),
    connect(mapStateToProps)
)(PathItems);

物品组成:

import React, { useState, useEffect } from "react";
import { Col, Row, Card } from "react-bootstrap";

const PathItem = ({ item, onInfoChange }) => {
    const [info, setInfo] = useState(null)

    useEffect(() => {
        onInfoChange(info); // pass info back to parent
    }, [info, onInfoChange]);

    const _onClick = event => {
        setInfo(item);
    }

    return (
        <React.Fragment>
            <Card as="a"
                  style={{cursor: 'pointer'}}
                  className={'mb-2'}
                  onClick={ _onClick }>
                <Card.Body>
                    <Row className="align-items-center">
                        <Col xs={1}>
                            <img
                                alt="Logo"
                                src="https://cdn2.iconfinder.com/data/icons/font-awesome/1792/arrows-alt-256.png"
                                width="25"
                                height="25"
                                className="d-inline-block align-top"/>
                        </Col>
                        <Col xs={7}>
                            <h5>{item.title}</h5>
                            {item.sDescript}
                        </Col>
                        <Col xs={4} className="text-right">
                            <label>{item.length}600 km</label>
                            <img
                                alt="Logo"
                                src="https://cdn4.iconfinder.com/data/icons/developer-set-3/128/right-512.png"
                                width="25"
                                height="25"
                                className="d-inline-block pull-right"
                            />
                        </Col>
                    </Row>
                </Card.Body>
            </Card>
        </React.Fragment>
    );
}

export default PathItem;

FullDecript 组件:

import React from "react";
import MapForm from "../Map/MapForm";

import { Col, Row, Button } from "react-bootstrap";
import { deleteItem } from "../../store/actions/progectActions";
import { useDispatch } from "react-redux";

const FullDecript = ({ id, title, fDescript }) => {
    const dispatch = useDispatch();

    const handleRemove = (e) => {
        e.preventDefault();
        dispatch(deleteItem(id));
    }

    return (
        <>
            <Row>
                <Col>
                    <h2>{title}</h2>
                </Col>
            </Row>
            <Row>
                <Col className="pb-2">
                    {fDescript}
                </Col>
            </Row>
            <Row>
                <Button variant="link">Add to favorite</Button>
                <Button variant="link" onClick={ handleRemove }>Delete</Button>
            </Row>
            <Row>
                <div>
                    <MapForm />
                </div>
            </Row>
        </>
    )
}

export default FullDecript;

和删除功能:

export const deleteItem = (id) => {
    return (dispatch, getState, { getFirestore }) => {
        // make async call to database
        const firestore = getFirestore();
        firestore.collection('pathDescription').doc(id).delete().then(
            () => {
                dispatch({ type: 'DELETE_ITEM_SUCCESS' });
            }).catch(err => {
            dispatch({ type: 'DELETE_ITEM_ERROR' });
        })
    }
}

减速机组件

const initialState = [{}];

export default function userInfo (state = initialState, action) {
    switch (action.type) {
        case 'ADD_ITEM':
            console.log('Add item text', action.textInfo);
            return state;
        case 'ADD_ITEM_ERROR':
            console.log('Add item text error', action.err);
            return state;
        case 'DELETE_ITEM_SUCCESS':
            console.log('Delete item succes');
            return state;
        case 'DELETE_ITEM_ERROR':
            console.log('Delete item error')
            return state;
        default:
            return state;
    }
}

组件 FullDecript 的内容保持不变

标签: reactjsfirebasereact-nativereduxgoogle-cloud-firestore

解决方案


您的组件如下所示:

            <Row>
                <Col className="pl-0 border-right border-dark" style={divStyle}>
                    {props.pathDescription && props.pathDescription.map(item => (
                        <Item
                            key={item.id}
                            item={item}
                            onInfoChange={setInfo}
                        />
                    ))}
                </Col>
                <Col>
                    {info !== null ? <FullDecript {...info}/> : null}
                </Col>
            </Row>

你的问题是,在删除 item 后,props.pathDescription大小为 0(因此.map不会渲染任何项目),但FullDecript仍然存在。那是因为你没有清除info. 您只需从pathDescription.

您可以在 Item 组件中执行此操作:

    useEffect(() => () => {
        onInfoChange(null); // pass null info back to parent, on unmount
    }, []);

删除项目时更新父信息。

Ps:它仍然需要更多的工作,因为你有 n 个项目,但只有一个描述元素。所以应该有一个select逻辑让我们只显示所选项目的详细信息。


推荐阅读