繁体   English   中英

内部和外部的函数render()

[英]Functions inside and outside render()

我刚刚开始学习React和JavaScript。 在我阅读了文档和教程之后,我看了一些示例项目,并尝试理清我还没有得到的内容。

然后我看到有些函数在render()函数中定义,有些函数在render()函数之外。

例如,对于render()外部:

handleClick(e) {
    e.preventDefault();
    e.target.parentElement.classList.toggle('open');
  }

在里面渲染()......

const divider = (divider, key) => {
      const classes = classNames( 'divider', divider.class);
      return (<li key={key} className={ classes }></li>);
    };

为什么它们看起来如此不同?你为什么要在render()里面有一些函数?

编辑:

另一个render()之外的函数示例:

hideMobile() {
    if (document.body.classList.contains('sidebar-mobile-show')) {
      document.body.classList.toggle('sidebar-mobile-show')
    }
  }

编辑2:在另一个线程中有人回答说,如果函数背后的逻辑很重,它应该在render()之外。 但是你为什么要在render()中使用函数呢?

官方网站上的例子

首先,如果我们想在开始时构建一个Clock,那么我们就尝试使用无状态函数对象创建一个面向对象,可维护的组件。

function Clock(props) {
  return (
    <div>
      <h1>Hello, world!</h1>
      <h2>It is {props.date.toLocaleTimeString()}.</h2>
    </div>
  );
}

function tick() {
   ReactDOM.render(
     <Clock date={new Date()} />,
     document.getElementById('root')
   );
}

setInterval(tick, 1000);

来自doc的引用

使Clock组件真正可重用和封装。 它将设置自己的计时器并每秒更新一次。

...理想情况下,我们想要写一次并自己更新时钟......

所以这里是React的精神,我们希望将这个函数对象转换为一个可以自我维护的类,所以现在我们涉及render() ,更具体地说我们涉及有状态的组件

Add a single empty method to it called render()
...
Clock is now defined as a class rather than a function.

然后我们得到:

class Clock extends React.Component {
    constructor(props) {
        super(props);
        this.state = {date: new Date()};
        this.clockCore = this.clockCore.bind(this);
    }

    componentDidMount() {
        this.timerID = setInterval(
          () => this.tick(),
           1000
        );
     }

     tick() {
         this.setState({
             date: new Date()
         });
     }

     clockCore() {
         return (<div>
            <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
         </div>);
     }

     render() {
        return this.clockCore();
     }
}

如您所知,如果组件的状态需要由setState()刷新,则再次触发render() setState()


更新

在我看来 ,没有必要在render()定义函数。 我对上面的原始示例进行了一些修改,以表明这一点。

从您提供的示例中,divider的用法可能如下:

const divider = (divider, key) => {
  const classes = classNames( 'divider', divider.class);
  return (<li key={key} className={ classes }></li>);
};

return (<ul>{this.state.dividerList?
    this.state.dividerList.forEach(divider) : null}</ul>);

我认为这样做的原因只是为了可维护性,有人可能希望所有DOM在render()创建代码,以便在返回DOM结构时很容易跟踪( 箭头函数很轻 ),但正如我所说它是主观的,它真的可以在外面定义。

在这种情况下, 我习惯在下面做,而且看起来你提供的更优雅,但是如果你在render()之外定义了这个函数,那么事情就会让我感到分心。

let dividers = [];
if (this.state.dividerList) {
    this.state.dividerList.forEach((divider, key) => {
        let classes = classNames( 'divider', divider.class);
        dividers.push((<li key={key} className={ classes }></li>));
    });
}

return (<ul>{dividers}</ul>);

因此,您提供的另一个针对DOM操作功能的功能是完全正确的,并且可以在外部定义。

每次state改变时都会调用render() 因此,每次state更改时,保留在render函数内的每个函数都将创建为一个新函数。 这意味着每次重新渲染时都会重新创建divider

handleClick是一个普通的对象函数。

render函数中编写的函数通常是那些处理组件重新render函数。

除此之外, handleClick是一个为每个Object / Component创建和访问的函数, divide是一个本地范围的函数,它们的功能可以完全相同。 但是, divider将在每个渲染上创建为新函数,这可能具有后续性能影响,而handleClick为已定义组件(Object)创建一次。

暂无
暂无

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

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