我开始学习 React。不同网站的一些人告诉大家,使用 refs 是一种不好的做法(是的,完全使用它们)。
真正的处理是什么?我将它附加到子组件(这样我可以访问内部的东西)是不是很糟糕?
谢谢!
我开始学习 React。不同网站的一些人告诉大家,使用 refs 是一种不好的做法(是的,完全使用它们)。
真正的处理是什么?我将它附加到子组件(这样我可以访问内部的东西)是不是很糟糕?
谢谢!
React 要求您考虑 react 方式,而 refs 是您几乎不需要使用的 DOM 的一种后门。为了彻底简化,react 的思维方式是,一旦状态发生变化,您将重新渲染依赖于该状态的 UI 的所有组件。React 将确保只更新 DOM 的正确部分,从而使整个事情变得高效并隐藏 DOM(有点)。
例如,如果您的组件托管一个 HTMLInputElement,那么在 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 的回答,并认为应该避免这些情况。这是一个例外。