Реагирование на совместное использование событий родительского дочернего компонента JS - PullRequest
0 голосов
/ 15 октября 2019

Ниже приведены мои реагирующие компоненты. Здесь я пытаюсь создать родительский компонент, который отвечает за получение события клавиатуры «keyPressed», и при нажатии любой клавиши следует удалить соответствующий дочерний компонент из вида.

Ваша помощьи предложения приветствуются.

РОДИТЕЛЬСКИЙ КОМПОНЕНТ Этот компонент отвечает за создание массива символов (az, AZ) и создание доски для отображения каждого символа в качестве дочернего элемента с именем ball.

import React, { Component } from "react";
import Ball from "./Ball";

export default class Board extends Component {
  constructor(props) {
    super(props);
    this.state = {
      letters: []
    };
    this.shuffle = this.shuffle.bind(this);
    this.handleEvent = this.handleEvent.bind(this);
  }

  componentDidMount() {
    const self = this;
    let letters = [];

    // small a - z
    for (let i = 97; i < 123; i++) {
      letters.push({ letter: String.fromCharCode(i), code: i });
    }

    // capital A - Z
    for (let i = 65; i < 91; i++) {
      letters.push({ letter: String.fromCharCode(i), code: i });
    }

    this.setState(state => ({
      letters: self.shuffle(letters)
    }));
  }

  shuffle(arr) {
    var ctr = arr.length,
      temp,
      index;

    // While there are elements in the array
    while (ctr > 0) {
      // Pick a random index
      index = Math.floor(Math.random() * ctr);
      // Decrease ctr by 1
      ctr--;
      // And swap the last element with it
      temp = arr[ctr];
      arr[ctr] = arr[index];
      arr[index] = temp;
    }
    return arr;
  }

  handleEvent(e) {
    const k = e.charCode;
    // HELP NEEDED HERE
    // Need to find matching children component of Ball to trigger its own setVisibility method.
  }

  render() {
    let ball = this.state.letters.map(item => {
      return <Ball key={item.code} properties={item} bouncing={true} />;
    });

    return (
      <div
        className="overlay-full game"
        onKeyPress={event => this.handleEvent(event)}
        tabIndex="0"
      >
        <div className="bubble-wrapper">{ball}</div>
      </div>
    );
  }
}

ДЕТСКИЙ КОМПОНЕНТ каждый компонент Ball должен иметь свое собственное состояние для видимости, если его состояние является видимым, то только он будет отображаться на экране, в противном случае он не должен делать ничего.

import React, { Component } from "react";

export default class Ball extends Component {
  constructor(props) {
    super(props);
    this.getRandomSize = this.getRandomSize.bind(this);
    this.getRandomColor = this.getRandomColor.bind(this);
    this.setVisibility = this.setVisibility.bind(this);
    this.state = {
      isVisible: true,
      code: this.props.properties.code,
      letter: this.props.properties.letter
    };

    this.ballRef = null;
    this.setBallRef = element => {
      this.ballRef = element;
    };
  }
  getRandomSize() {
    const sizes = ["size-1", "size-2", "size-3", "size-4"];
    return sizes[Math.floor(Math.random() * 4)];
  }
  getRandomColor() {
    const colors = [
      "#55efc4",
      "#81ecec",
      "#74b9ff",
      "#a29bfe",
      "#00b894",
      "#00cec9",
      "#0984e3",
      "#6c5ce7",
      "#ffeaa7",
      "#fab1a0",
      "#ff7675",
      "#fd79a8",
      "#fdcb6e",
      "#e17055",
      "#d63031"
    ];
    return colors[Math.floor(Math.random() * 15)];
  }
  setVisibility(key) {
    if (this.state.code === key) {
      this.setState(state => ({
        isVisible: false
      }));
    }
  }
  render() {
    const { code, letter } = this.state;
    const isBouncing = this.props.bouncing ? "bouncing" : "";
    const isVisible = this.state.isVisible;
    const size = this.getRandomSize();
    const inlineStyle = {
      backgroundColor: this.getRandomColor()
    };

    if (isVisible) {
      return (
        <div
          className={`ball-${code} ${size} ${isBouncing}`}
          style={inlineStyle}
          ref={this.setBallRef}
        >
          {letter}
        </div>
      );
    } else {
      return null;
    }
  }
}

Ответы [ 2 ]

2 голосов
/ 15 октября 2019

Я думаю, вам нужно использовать Redux для решения таких проблем, чтобы вам не пришлось попадать в центр управления состояниями во всем приложении.

Но в случае, если вам нужно перейти к текущему сценарию,Вы должны использовать ссылки. React предоставляет CreateRef API. Используя это, вы можете получить ссылку на ваш компонент Ball и вызвать его метод setVisibility. Но перед этим вам нужно поднять состояние соответствующего компонента Ball до родительского, предоставив функцию обратного вызова.

0 голосов
/ 15 октября 2019

Извините, я довольно хорошо знаю все о программировании, поэтому мои предложения могут быть не самыми лучшими.

for (i in letters) { 
if (ball == letters[i]) 
{
ball.setvisibility = false;
}
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...