Как мне сопоставить диспетчеризацию с реквизитами внутри рекурсивно вложенного компонента, используя React и Redux? - PullRequest
0 голосов
/ 26 апреля 2020

Я пытаюсь создать приложение, которое отображает семейное древо для React с использованием Redux. Каждый человек отображается в окне со строками, ведущими к его родителям. Я хочу иметь функцию, при которой, если вы нажмете на «карточку» человека, вы увидите всплывающее окно с дополнительной биографической информацией. Проблема, с которой я столкнулся, связана с отображением действия диспетчеризации внутри любого компонента, расположенного ниже по дереву, чем человек уровня root. Это работает, как и ожидалось, когда я нажимаю на «Джона» наверху, но любой из его предков и ломается. Надеюсь, я просто упускаю что-то очевидное!

Here is the family tree with no bio card

This is the desired result ( with proper information ) upon clicking a family member

Here is the error message that I receive

Вот компоненты:

import React, {Component} from 'react';
import {connect} from 'react-redux';
import {getFamily} from '../redux/family.actions'
import "./Family.css";
import Person from './Person';

class Family extends Component {
    render() {
        const {rootPerson} = this.props;
        return (
            <div className="family family-container">
                <ul>
                    <Person key={rootPerson.id} info={rootPerson}/>
                </ul>
            </div>
        )
    }
}

const mapStateToProps = (state) => ({
    rootPerson: state.family.allFamilyMembers[0]
});

const mapDispatchToProps = dispatch => ({
    getFamilyFromStore: () => dispatch(getFamily())
});

export default connect(mapStateToProps, mapDispatchToProps)(Family);
import React from 'react';
import {connect} from 'react-redux';

import {selectPerson} from '../redux/family.actions'

import "./Person.css";

const Person = props => (
    <li className="oc-hierarchy" onClick={() => props.selectPerson(props.info)}>
        <div className="card card-body oc-node">
            <h1>{props.info.name}</h1>
        </div>

        {props.info && props.info.parents && props.info.parents.length > 0 && (
                <ul>
                    {props.info.parents.map(child => (
                        <Person info={child} />
                        ))}
                </ul>
            )} 
    </li>
);

const mapDispatchToProps = dispatch => ({
    selectPerson: (person) => dispatch(selectPerson(person))
});

export default connect(null, mapDispatchToProps)(Person);
import React from 'react';
import {connect} from 'react-redux';

import './App.css';

import Family from './components/Family';
import PersonBio from './components/PersonBio';

function App({selectedPerson}) {

  return (
    <div className="App">
        <Family />
        {selectedPerson == null ? null : <PersonBio />}
    </div>
  );
}

const mapStateToProps = (state) => ({
    selectedPerson: state.family.selectedPerson
});

export default connect(mapStateToProps) (App);
export const selectPerson = (person) => ({
    type: 'SELECT_PERSON',
    payload: person
})
const INITIAL_STATE = {
    allFamilyMembers: [
        {
            id:0,
            name: 'John',
            parents: [
                {
                    id:1,
                    name: 'Bill',
                    parents: [
                        {
                            id:3,
                            name: 'Bob',
                            parents: [
                            ]
                        },
                        {
                            id:4,
                            name: 'Barb',
                            parents: [
                            ]
                        },
                    ]
                },
                {
                    id:2,
                    name: 'Mary',
                    parents: [
                        {
                            id:5,
                            name: 'Matt',
                            parents: [
                                {
                                    id:7,
                                    name: 'Mark',
                                    parents: [
                                    ]
                                },
                                {
                                    id:8,
                                    name: 'Ruth',
                                    parents: [
                                    ]
                                },
                            ]
                        },
                        {
                            id:6,
                            name: 'Marge',
                            parents: [
                            ]
                        },
                    ]
                }
            ]
        }
    ],
    selectedPerson: null
}

const familyReducer = (state = INITIAL_STATE, action) => {
    switch (action.type) {
        case 'GET_FAMILY':
            return state;
        case 'SELECT_PERSON':
            return {
                ...state,
                selectedPerson: action.payload
            };
        default:
            return state;
    }
}

export default familyReducer;

1 Ответ

2 голосов
/ 27 апреля 2020

На самом деле, вы не знаете основы ReactJS, вы никогда не передавали функцию selectPerson компоненту Person, обратите внимание на эту часть вашего кода:

<Person key={rootPerson.id} info={rootPerson}/>

Вы должны передать selectPerson в эту строку. в противном случае вы получаете его как undefined внутри Person компонента

<Person key={rootPerson.id} info={rootPerson} selectPersion={() => {}} />

Теперь объявляется selectPerson, и вы получаете функцию noOp внутри компонента Person вместо получения undefined. это причина вашей проблемы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...