繁体   English   中英

React JS 父子组件事件分享

[英]React JS Parent Child Component Events Sharing

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

感谢您的帮助和建议。

PARENT COMPONENT该组件负责创建字符(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 组件都应该有自己的 state 以查看其 state 是否可见,而不是仅在屏幕上呈现,否则它什么也不做。

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;
    }
  }
}

我认为您需要使用 Redux 来解决此类问题,这样您就不会在整个应用程序的状态管理过程中陷入困境。

但是,如果您需要 go 与当前场景,那么您需要使用 refs。 React 提供了CreateRef api。 使用它,您可以获得对 Ball 组件的引用并触发它的 setVisibility 方法。 但在此之前,您需要通过提供回调 function 将相应 Ball 组件的 state 提升到父组件。

抱歉,我对整个编程非常了解,所以我的建议可能不是最好的。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM