What is the bad practice with refs in React?

I am learning React. Some guys from different sites tell everyone that using links is bad practice (yes, using them at all).

What is the real deal with him? Is it something bad that I will attach it to, for example, a child component (so that I can access the internal material)?

Thanks!

+5
source share
2 answers

React requires you to think about how to react on the way , and refs is a backdoor in the DOM that you almost never need to use. To simplify the radical, reactive way of thinking is that after changing the state you re-display all the components of your interface that depend on this state. React will take care of updating only the correct DOM bits, which made it all effective and hid the DOM from you (kinda).

For example, if your component contains an HTMLInputElement, in React you will include an event handler to track changes to the input element. Whenever a user enters a character, the event handler lights up, and in your handler you update your state with the new value of the input element. A change in state triggers the hosting component to re-render, including an input element with a new value.

Here i mean

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> 

Note that at any time when the input value changes, the handler is called, the setState function is called, and the component will be completely redrawn.

In general, it’s a bad practice to think of links because you might be tempted to just use refs and do something, say, in the jQuery way, which is not the purpose of the React / mindset architecture.

The best way to better understand this is to create more React applications and components.

+10
source

Hmm ... Not sure if this will respond as an answer, but it has become too long for comment.

Imagine that you have a dashboard containing widgets showing the various states of the system. Each widget has its own data source and its own controls. Perhaps they are updated from time to time. However, when the user wants to see the updated view of the system, at the toolbar level there is a button "Update". The implementation of such a button is not trivial.

If you are in the Redux application, you will have a choice - "faking" dispatch('refresh') for all children. To separate it, each widget after loading registers an action, so the parent simply goes through all the actions and launches them when a mandatory update is required.

On a system without Redux / Flux or in more complex / dynamic scenarios, this may not be possible or may not be so simple. Then it might be better, more difficult, to expose the refresh method for all widgets, and then get access to it from the parent (or, rather, the owner):

 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> ); } } 

Something like this, with less detail, of course.

As a side note, I confirmed @skav's answer and I think these scenarios should be avoided. This is an exception.

CodePen Example

+2
source

Source: https://habr.com/ru/post/1259652/


All Articles