#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, и поэтому цикл повторяется. Я не уверен, имеет ли это смысл, но это единственное, что я могу четко видеть. Однако все еще остается вопрос о третьем компоненте, он отлично загружается без ошибок и не захватывает программу, как я ожидал бы, если следовать теории выше. Поэтому я совершенно не понимаю, в чем проблема, и любые идеи будут с благодарностью приняты.