从倒数儿童开始反应集状态

时间:2019-02-04 18:02:01

标签: javascript reactjs ecmascript-6

我有一个<CountDown/>组件,我想保留它自己的逻辑,以便可以在应用程序中的其他位置重用。

当计数达到0时,我很难解释如何在同级组件(​​即setState)上show:true<List/>

当前,这是组件的层次结构:

export default class App extends Component {
  state = { show: false };

  render() {
    return (
      <div className="App">
        <Countdown />
        <List {...this.state} />
      </div>
    );
  }
}

我想展示<List/>的内容

const fruits = ["banana", "apple", "peach"];
export const List = ({ show }) => fruits.map(fruit => <li className={show ? "show" : "hide"}>{fruit}</li>);


一旦currentCount = 0

import React, { Component } from "react";

export default class Countdown extends Component {
  state = { currentCount: 3 };

  // decrement timer method
  timer() {
    this.setState({
      currentCount: this.state.currentCount - 1
    });
    //clear interval
    if (this.state.currentCount < 1) {
      clearInterval(this.intervalId);
    }
  }

  // decrement every second i.e 1000
  componentDidMount() {
    this.intervalId = setInterval(this.timer.bind(this), 1000);
  }

  // Perform any necessary cleanup in this method, such as invalidating timers, canceling network requests, or cleaning up any subscriptions that were created in componentDidMount().
  componentWillUnmount() {
    clearInterval(this.intervalId);
  }
  render() {
    const { currentCount } = this.state;
    return <h1>{currentCount}</h1>;
  }
}

我的挣扎在于,如果我要将currentCount的状态提升到主<App/>,我将失去使用自己的状态和生命周期方法控制<CountDown/>的能力。此外,我希望CountDown具有自己的逻辑集,以便可以在应用程序中需要的任何地方重用和移动它。

问题:一旦倒数达到0,如何将show(作为道具传递)的状态设置为true?

这里是code sandbox

2 个答案:

答案 0 :(得分:4)

在App中定义一个将状态show设置为true的方法:

onFinish = () => {
   this.setState({ show: true });
};

现在将其作为道具发送给CountDown:

<Countdown onFinish={this.onFinish} />

现在,一旦您的本地状态为零,就调用它:

if (this.state.currentCount < 1) {
    clearInterval(this.intervalId);
    this.props.onFinish();
}

这里是your Sandbox's fork

由于setState以异步方式工作,所以我还将代码的最后一部分移到了setState的回调上。

答案 1 :(得分:2)

您可以在showList()中创建<App>并将其传递给<CountDown />我已经按照部分代码进行了更改

timer() {
    this.setState({
      currentCount: this.state.currentCount - 1
    });
    //clear interval
    if (this.state.currentCount < 1) {
      clearInterval(this.intervalId);
      //This line is edited
      this.props.showList();
    }
  }

应用组件

export default class App extends Component {
  state = { show: false };
  showList = () =>{
    this.setState({show:true});
  }
  render() {
    return (
      <div className="App">
        <Countdown showList={this.showList}/>
        <List {...this.state} />
      </div>
    );
  }
}

Codesandbox