Дочерний компонент в react не позволяет родительскому компоненту импортировать хранилище redux

#javascript #reactjs #react-native #redux #react-redux

#javascript #reactjs #react-native #redux #react-redux

Вопрос:

У меня есть два компонента react, которые работают независимо друг от друга, но при подключении, похоже, нарушают ядро моей программы. Моя настройка такова: Redux store -> MusicList.js (первый компонент) —> AppNavbar.js (второй компонент внутри MusicList.js ). Независимо друг от друга хранилище redux отлично работает с первым компонентом, но когда я подключаю свой второй компонент к MusicList.js это нарушает импорт моего магазина. Есть еще и третий компонент «Items.js » который связан с MusicList.js точно так же, как и второй компонент, он также использует хранилище redux в качестве опоры, и все же он отлично работает, не нарушая работу программы.

Вот этот код:

MusicList.js:

 import React, {Component, useState } from "react";
import Items from "./Items";
import AddItem from "./AddItem";
import { connect } from "react-redux";
import { getItems, deleteItem, addItem, toggleItem } from "../actions/itemActions"
import PropTypes from "prop-types";
import AppNavbar from "./AppNavbar.js";

class MusicList extends Component {

    // Both componentWillMount and componentDidMount fail to get the items from my databse when the AppNavbar.js is connected. 
    // They both work when I comment out AppNavbar.js.
    // The setTimeout changes nothing.
    componentWillMount() {
        console.log("test")
        this.props.getItems();
        const func = () => {
            console.log(this.props.item)
        }
        setTimeout(func, 5000);
    }

    toggle = (id) => {
        this.props.toggleItem(id)
        console.log(this.props.item.items)
    }

    delItem = (id) => {
        this.props.deleteItem(id)
    }

    addItem = (item, url) => {
        this.props.addItem(item, url)
        console.log(this.props.item.items)
    }

    render() {
        
        const { items } = this.props.item
        console.log(items)

        return (
            
            <div>

                <div class="sticky-top">
                    // In this example the Appnavbar is commented out. 
                    // The program will get the items from the backend.
                    {/* <AppNavbar toggle={this.toggle} items={items}/> */}
                    <AddItem addItem={this.addItem}/>
                </div>

                <Items items={items} toggle={this.toggle} delItem={this.delItem} />

            </div>

        )
        
    }

}

MusicList.propTypes = {
    getItems: PropTypes.func.isRequired,
    deleteItem: PropTypes.func.isRequired, 
    addItem: PropTypes.func.isRequired,
    toggleItem: PropTypes.func.isRequired,
    item: PropTypes.object.isRequired
}

const mapStateToProps = (state) => ({
    item: state.item
})

export default connect(mapStateToProps, { getItems, deleteItem, addItem, toggleItem})(MusicList);
 

AppNavbar.js:

 import React, { Component } from "react";
import {
    Navbar,
    NavbarBrand,
    Nav,
    Button
} from "react-bootstrap";
import './style.css';
import PropTypes from "prop-types";

class AppNavbar extends Component {

    playTrack = (track_index, items, placeholderTitle, isPlaying, isShuffling) => { 

        console.log(items)
        
        isPlaying = true;

        // playpause_btn.innerHTML = '<i class="fa fa-pause-circle fa-5x"></i>';
        
        // Load a new track
        if (isShuffling) {
            track_index = Math.floor(Math.random() * items.length)

            items[track_index].this.props.toggle()

            // this.props.toggle(trackIndexToID)

        }
        else {
            items[track_index].this.props.toggle()
        }
        
        // Update details of the track 
        placeholderTitle = this.props.items[track_index].name; 
        
        // Move to the next track if the current finishes playing 
        // using the 'ended' event 

        // items[track_index].addEventListener("ended", nextTrack); 

    }

    playpauseTrack = (track_index, isPlaying, items, placeholderTitle, isShuffling, playTrack, pauseTrack) => { 
        // Switch between playing and pausing 
        // depending on the current state 
        if (!isPlaying) playTrack(track_index, items, placeholderTitle, isPlaying, isShuffling); 
        else pauseTrack(track_index, items, placeholderTitle, isPlaying); 
    }

    pauseTrack = (track_index, items, placeholderTitle, isPlaying) => {

        // Pause the loaded track 
        
        isPlaying = false; 
        
        // Replace icon with the play icon 
        // playpause_btn.innerHTML = '<i class="fa fa-play-circle fa-5x"></i>';

        items[track_index].this.props.toggle()
    }
        
    nextTrack = (track_index, isLooping, items, playTrack) => { 
        // Go back to the first track if the 
        // current one is the last in the track list 
        if (track_index < items.length - 1 amp;amp; !isLooping) {
            track_index  = 1; 
        }
        else if (isLooping) {
            track_index = track_index
        }
        else track_index = 0; 
        
        // Load and play the new track 
        playTrack(track_index); 
    } 
        
    prevTrack = (track_index, isLooping, items, playTrack) => { 
        // Go back to the last track if the 
        // current one is the first in the track list 
        if (track_index > 0 amp;amp; !isLooping) {
            track_index -= 1;
        }
        else if (isLooping) {
            track_index = track_index
        }
        else track_index = items.length; 
        // Load and play the new track 
        playTrack(track_index); 
    }


    // Connect to loop track icon
    loopTrack = (element, isLooping, isShuffling, loopOn, shuffleOff, LoopOff) => {
        if (!isLooping) {
            loopOn(element, isLooping);
            shuffleOff(element, isShuffling);
        }
        else LoopOff(element, isLooping);
    }

    // Connect to shuffle track icon
    shuffleTrack = (element, isLooping, isShuffling, shuffleOn, LoopOff, shuffleOff) => {
        if (!isShuffling) {
            shuffleOn(element, isShuffling);
            LoopOff(element, isLooping);
        }
        else shuffleOff(element, isShuffling);
    }

    loopOn = (element, isLooping) => {
        isLooping = true;
        element.style.opacity = "1"
        console.log("1"   isLooping)
    }

    LoopOff = (element, isLooping) => {
        isLooping = false;
        element.style.opacity = "0.8"
        console.log("2"   isLooping)
    }

    shuffleOn = (element, isShuffling) => {
        isShuffling = true;
        element.style.opacity = "1"
        console.log("3"   isShuffling)
    }

    shuffleOff = (element, isShuffling) => {
        isShuffling = false;
        element.style.opacity = "0.8"
        console.log("4"   isShuffling)
    }

    render() {

        console.log(this.props.items)
        var placeholderTitle = "Who asked (Feat: Nobody)";
        let track_index = 0;
        let isShuffling = false;
        let isLooping = false;
        let isPlaying = false;

        return (

            <Navbar className="Navbar">
                <NavbarBrand id="Logo" href="#home">
                    <img
                    alt=""
                    src={require('D:/Parrot/Desktop/Dev/Duplicate/Embedded_Music_Player/client/src/images/Logo-Smaller.png')}
                    />
                </NavbarBrand>
                <Navbar.Toggle aria-controls="basic-navbar-nav" />
                <Navbar.Collapse id="basic-navbar-nav">

                    <Nav className="mr-auto">

                        <ul className="navbar-nav">

                            <li>
                                <a href="#" className="Title">
                                    Embedded Music
                                </a>
                            </li>
                        
                        </ul>

                    </Nav>

                    <Nav className="mr-auto">

                    <div id="PlayerBox">

                        <ul className="navbar-nav">

                            <li>

                                <header id="Player">
                                    Now Playing:
                                </header>

                                <header id="Player">
                                    {placeholderTitle}
                                </header>

                                <img class="Previous transparent" id="Player" 
                                alt=""
                                onClick={this.prevTrack(track_index, isLooping, this.props.items, this.playTrack())}
                                src={require('D:/Parrot/Desktop/Dev/Duplicate/Embedded_Music_Player/client/src/images/Previous-smallest.png')}
                                />

                                <img class="playpauseTrack transparent" id="Player"
                                alt=""
                                onClick={this.playpauseTrack(track_index, isPlaying, this.props.items, placeholderTitle, isShuffling, this.playTrack(), this.pauseTrack())}
                                src={require('D:/Parrot/Desktop/Dev/Duplicate/Embedded_Music_Player/client/src/images/Play-smallest.png')}
                                />
                                
                                <img class="Next transparent" id="Player" 
                                alt=""
                                onClick={this.nextTrack(track_index, isLooping, this.props.items, this.playTrack())}
                                src={require('D:/Parrot/Desktop/Dev/Duplicate/Embedded_Music_Player/client/src/images/Next-smallest.png')}
                                />

                                <img class="Loop transparent" id="Player"
                                alt=""
                                onClick={this.loopTrack(this, isLooping, isShuffling, this.loopOn(), this.shuffleOff(), this.LoopOff())}
                                src={require('D:/Parrot/Desktop/Dev/Duplicate/Embedded_Music_Player/client/src/images/Loop-small.png')}
                                />

                                <img class="Shuffle transparent" id="Player" 
                                alt=""
                                onClick={this.shuffleTrack(this, isLooping, isShuffling, this.shuffleOn(), this.LoopOff(), this.shuffleOff())}
                                src={require('D:/Parrot/Desktop/Dev/Duplicate/Embedded_Music_Player/client/src/images/Shuffle-smallest.png')}
                                />

                            </li>

                        </ul>

                    </div>

                    </Nav>

                </Navbar.Collapse>
            </Navbar>
        )
    }
}

AppNavbar.propTypes = {
    toggle: PropTypes.func.isRequired,
    items: PropTypes.array.isRequired
}


export default AppNavbar;
 

Items.js:

 import React, { Component } from 'react';
import Item from "./Item";
import PropTypes from "prop-types";

class Items extends Component {
    
    render() {

        return this.props.items.map((item) => (

            <div>

                <Item key={item._id} item={item} toggle={this.props.toggle} delItem={this.props.delItem} isOpen={item.isOpen}/>

            </div>

            ));
    }
}

// PropTypes
Items.propTypes = {
    items: PropTypes.array.isRequired
}

export default Items;
 

Второй компонент довольно длинный, но когда я комментирую любые вызовы «this.props.items», программа работает и MusicList.js способен получать элементы из серверной части и регистрировать их. Если я ничего не комментирую, я получаю сообщение об ошибке «элементы не определены», и мои логи в MusicList.js покажите массив элементов как пустой. Моя основная теория заключается в том, что парадоксальным образом ошибка в AppNavbar, которая показывает, что элементы не определены, эффективно захватывает всю программу, и музыкальный список никогда не монтируется, а поскольку он никогда не монтируется, он никогда не получает элементы и, следовательно, никогда не может передать элементы в AppNavbar, и поэтому цикл повторяется. Я не уверен, имеет ли это смысл, но это единственное, что я могу четко видеть. Однако все еще остается вопрос о третьем компоненте, он отлично загружается без ошибок и не захватывает программу, как я ожидал бы, если следовать теории выше. Поэтому я совершенно не понимаю, в чем проблема, и любые идеи будут с благодарностью приняты.