【问题标题】:Rewrite shorter version function重写更短的版本功能
【发布时间】:2020-03-07 21:53:51
【问题描述】:

我有一个调用特定状态的函数,但有一条半相同的行。这是我的功能;

DoThis(type) {
   if (type === 'a') {
      this.setState({ activeA: { display: 'block', opacity: 1 } }, () => setTimeout(() => {
         this.setState({ activeA: { opacity: 0 } }, () => setTimeout(() => {
            this.setState({ activeA: { display: 'none' } })
         }, 300))
      }, 2000));
   } else if (type === 'b') {
      this.setState({ activeB: { display: 'block', opacity: 1 } }, () => setTimeout(() => {
         this.setState({ activeB: { opacity: 0 } }, () => setTimeout(() => {
            this.setState({ activeB: { display: 'none' } })
         }, 300))
      }, 2000));
   } // ...some other active(n) conditions.
}

这里很乱,我只是希望它没有拥堵。

这是我的状态:

this.state ={
   activeA: { display: 'none', opacity: 0 },
   activeB: { display: 'none', opacity: 0 },
   // ...some other active(n) states...
}

有什么办法可以解决这类问题?

【问题讨论】:

  • this.setState({ `active${type.toUpperCase()}`: ... })?
  • 你想用所有这些 setStates 完成什么?这对我来说根本没有意义。为什么这一切都不在一个 setState 中,那些 setTimeouts 又在做什么?
  • 首先对多个 if else 语句使用 switch case。然后制作 2 个功能,一个使状态处于活动状态,另一个使状态处于非活动状态,或者使一个功能只是切换状态。您可以使用字符串文字作为 javascript 对象的键,如下所示:` {'active'+stateToActivate :{ display:"block", opacity:1 }}` 这就是@jonrsharpe 试图告诉你的。因此,您只需将参数作为该状态的名称。
  • @DaveMoreno,你可以在渲染函数opacity中推导出display的值const display = state.opacity > 0 ? "" : "none"; (这里不要使用block,让它回退到任何东西在 CSS 中定义) 这已经消除了第二个setTimeout,包括第三个setState
  • @Mirakurun。这是自关闭模式的一个版本。基本上,当我单击该特定按钮时,会弹出状态之前的某个模式,并自行关闭。

标签: javascript reactjs ecmascript-6 react-functional-component


【解决方案1】:

使用template stringcomputed property name 的组合:

DoThis(type) {
  const fieldName = `active${type.toUpperCase()}`;
  this.setState({[fieldName]: { display: 'block', opacity: 1 } }, () => setTimeout(() => {
     this.setState({ [fieldName]: { opacity: 0 } }, () => setTimeout(() => {
        this.setState({ fieldName]: { display: 'none' } })
     }, 300))
  }, 2000));
}

模板字符串让您可以轻松构造具有复杂 JavaScript 值的字符串:

  const myString = "some text";
  const myTemplateString = `you can insert ${myString} into a template string`;
  // myTemplateString = "you can insert some text into a template string"

计算的属性值让您可以在不提前知道(即“硬编码”)字段是什么的情况下为对象的字段赋值:

  const myFieldName = "pizza";
  const myObject = {
    [myFieldName]: "delicious"
  };
  // myObject = {pizza: "delicious"}

【讨论】:

  • 肯定会试试这个。
【解决方案2】:

为了逃避回调地狱,你可以像这样添加一个简单的函数:

const delay = (time = 0) => new Promise(r => setTimeout(r, time));

然后以线性方式重写:

async DoThis(type) {
    let key = 'active' + type.toUpperCase();

    this.setState({[key]: {display: 'block', opacity: 1}})
    await delay(300);
    this.setState({[key]: {opacity: 0}});
    await delay(2000);
    this.setState({[key]: {display: 'none'}});
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-19
    • 2021-03-27
    • 2012-09-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多