在React中使用refs有什么不好的做法?
What's a bad practice with refs in React?
我正在学习React。不同网站的一些人告诉大家使用refs是一种不好的做法(是的,使用它们)。
这到底是怎么回事?我将把它附加到一些不好的东西,例如,子组件(这样我就可以访问内部的东西)?
谢谢!
React需要你考虑React的方式和refs是一种你几乎不需要使用的DOM的后门。为了彻底简化,反应的思维方式是,一旦状态发生变化,您就重新呈现所有依赖于该状态的UI组件。React会确保只更新DOM的正确部分,使整个事情变得高效,并对你隐藏DOM(有点)。
例如,如果你的组件承载了一个htmlputelement,那么在React中你将连接一个事件处理程序来跟踪对输入元素的更改。每当用户键入字符时,事件处理程序就会触发,在处理程序中,您将使用输入元素的新值更新状态。状态的改变会触发宿主组件重新呈现自身,包括带有新值的输入元素。
我的意思是
import React from 'react';
import ReactDOM from 'react-dom';
class Example extends React.Component {
state = {
inputValue: ""
}
handleChange = (e) => {
this.setState({
inputValue: e.target.value
})
}
render() {
const { inputValue } = this.state
return (
<div>
/**.. lots of awesome ui **/
/** an input element **/
<input value={inputValue} onChange={this.handleChange}} />
/** ... some more awesome ui **/
</div>
)
}
}
ReactDOM.render( <Example />, document.getElementById("app") );
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app">
</div>
请注意,每当输入值发生变化时,处理程序被调用,setState被调用,组件将重新完整地呈现自身。
考虑refs通常是不好的做法,因为你可能会试图使用refs,并以JQuery的方式做事,这不是React架构/心态的意图。
真正更好地理解它的最好方法是构建更多的React应用程序&组件。
嗯…我不确定它是否符合答案,但对于评论来说,它太长了。
假设您有一个仪表板,其中包含显示系统各种状态的小部件。每个小部件都有自己的数据源和控件。也许他们甚至不时地刷新。但是,当用户想要查看系统的更新视图时,在仪表板级别有一个"刷新"按钮。实现这样一个按钮不是小事。
如果您在Redux应用程序中-您将有一个选择-为所有孩子"伪造"dispatch('refresh')
。为了解耦,每个小部件在加载时注册一个动作,这样当需要命令式刷新时,父部件只需遍历所有动作并触发它们。
在非Redux/Flux系统中,或者在更复杂/动态的场景中,这可能是不可能的,或者可能不那么直接。从复杂性的角度来看,在所有小部件上公开refresh
方法,然后从父(或者更确切地说是所有者)访问它可能会更好:
class WidgetA extends React.Component {
refresh() {
console.log('WidgetA refreshed');
}
render() {
return (
<h3>WidgetA</h3>
);
}
}
class WidgetB extends React.Component {
refresh() {
console.log('WidgetB refreshed');
}
render() {
return (
<h3>WidgetB</h3>
);
}
}
class Dashboard extends React.Component {
constructor() {
super();
this.onRefresh = this.handleRefresh.bind(this);
this.onRegister = this.handleRegister.bind(this);
this.widgets = [];
}
handleRegister(widget) {
this.widgets.push(widget);
}
handleRefresh() {
this.widgets.forEach((widget) => {
widget.refresh();
});
}
render() {
return (
<div>
<button onClick={this.onRefresh}>Refresh</button>
<hr />
<WidgetA ref={this.onRegister} />
<WidgetB ref={this.onRegister} />
</div>
);
}
}
类似的,当然不那么冗长。
作为旁注,我给@skav的答案点赞,并认为这些场景应该避免。这是个例外。
CodePen示例
- 我可以在React应用程序中使用什么作为Angular的等价物;s$http.get
- 在 React JS 中,什么时候应该使用存储而不是直接操作视图的状态
- 将 react-redux 与基于事件的第三方库一起使用的最佳方法是什么?
- 如果React.js是V,那么在MVC中,其他字母是什么
- 与kadira相比,使用react路由器有什么好处:流星流路由器
- ECMA 6,React Native和Redux:这个句法糖是什么意思
- @internal react 代码中的 JavaScript 文档标签,是 jsdoc、闭包还是其他什么
- 在同构的React web应用程序中,选择服务器渲染的最佳方式是什么
- 建立React 0.12项目的正确方法是什么
- meteor / react - “readOnly”属性有什么作用
- 什么是 react 中的父子耦合以及它与上下文的关系
- 在 React-Leaflet 库中为
- React Router 如何处理 onEnter 背后的逻辑是什么?
- ReactJS - 在 react 类中初始化 jquery 插件的标准方法是什么
- 在 react-native 中,我们使用 styleSheet.create.我们在 reactjs 中使用什么
- React(来自Facebook的应用程序框架)和react.js(JS的反应式扩展)之间有什么区别/相似之处
- React的setState是异步的还是什么
- React.addons.batchedUpdates API的目的是什么
- 使用React JS.12,所有者如何知道它被分配了什么ref
- React.js中的组件类是什么