[英].map() working outside of render function, but fails when used inside 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.