React JS父子组件事件共享

时间:2019-10-15 13:02:10

标签: javascript reactjs ecmascript-6

下面是我的react组件,在这里我试图创建Parent组件,该组件负责获取键盘事件“ keyPressed”,无论按下哪个键,都应该从视图中删除匹配的子组件。

我们非常感谢您的帮助和建议。

父组件 该组件负责创建字符(a-z,A-Z)数组,并创建一个板以将每个字符显示为名为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 个答案:

答案 0 :(得分:2)

我认为您需要使用Redux来解决此类问题,以免出现在管理整个应用程序状态的过程中。

但是如果您需要使用当前方案,则需要使用refs。 React提供CreateRef api。使用此方法,您可以获取对Ball组件的引用并触发它的setVisibility方法。但是在此之前,您需要通过提供回调函数将相应Ball组件的状态提升到父组件。

答案 1 :(得分:0)

对不起,我很了解整个编程知识,所以我的建议可能不是最好的。

for (i in letters) { 
if (ball == letters[i]) 
{
ball.setvisibility = false;
}
}