【问题标题】:React JS Parent Child Component Events SharingReact JS 父子组件事件分享
【发布时间】:2019-10-15 13:02:10
【问题描述】:

下面是我的反应组件,这里我正在尝试创建负责获取键盘事件“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;
    }
  }
}

【问题讨论】:

  • 您无法从父组件控制子组件的方法,而是必须将状态提升到父组件,然后将其传递给您的子组件,因此在您的情况下,isVisible 需要向上移动,然后设置其状态在父组件中,一旦更改,它将强制重新渲染子组件。
  • 感谢您的回答,我确实将可见状态移至父组件,并且每当父状态更新时,React 都会巧妙地呈现子组件。

标签: javascript reactjs ecmascript-6


【解决方案1】:

我认为您需要使用 Redux 来解决此类问题,以免您在管理整个应用程序的状态时遇到麻烦。

但如果您需要使用当前场景,那么您需要使用 refs。 React 提供CreateRef api。使用它,您可以获得对 Ball 组件的引用并触发它的 setVisibility 方法。但在此之前,您需要通过提供回调函数将各个 Ball 组件的状态提升到父组件。

【讨论】:

  • 肯定也会尝试这种方法。对我来说看起来更合乎逻辑。
【解决方案2】:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-12-26
    • 2017-11-23
    • 2021-08-20
    • 2021-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多