Hola usuario de nuestra página web, descubrimos la solución a lo que estabas buscando, continúa leyendo y la hallarás a continuación.
Solución:
Entiendo que las funciones de flecha hacen que las cosas sean más eficientes al no recrear las funciones cada vez que se hace referencia a ellas
Este es no true.
Las funciones de flecha manejan el this
contexto de una manera léxica, donde la función “normal” lo hace dinámicamente. Escribí sobre esto key palabra en profundidad si necesita más información al respecto.
En ambos ejemplos de la función de flecha en línea, está creando una nueva instancia de función en cada render
.
Esto creará y pasará una nueva instancia en cada renderizado.
onClick=() =>
En el tercer ejemplo, solo tiene una instancia.
Esto solo pasa una referencia a una instancia ya existente
onClick=this.myHandler
En cuanto a los beneficios de las funciones de flecha como campos de clase (hay una pequeño lado, lo publicaré en la parte inferior de la respuesta), si tiene un controlador de función normal que necesita acceder a la instancia actual del class
vía this
:
myHandler()
// this.setState(...)
Necesitarás explicitar bind
es para el class
.
El enfoque más común será hacerlo en el constructor
porque se ejecuta solo una vez:
constructor(props)
super(props);
this.myHandler = this.myHandler.bind(this);
Sin embargo, si usa una función de flecha como controlador, no es necesario bind
es para el class
porque como se mencionó anteriormente, la función de flecha usa un contexto léxico para this
:
myHandler = () =>
// this.setState(...)
Con ambos enfoques, usará el controlador de esta manera:
La principal razón para adoptar este enfoque:
this.myHandler(someParameter)>
Es si desea pasar parámetros al controlador junto al nativo event
que se pasan, lo que significa que desea pasar un parámetro hacia arriba.
Como se mencionó, esto creará una nueva instancia de función en cada render.
(Hay un mejor enfoque para esto, sigue leyendo).
Ejemplo de ejecución para tal caso de uso:
class App extends React.Component
constructor(props)
super(props);
this.state =
items: [ name: 'item 1', active: false , name: 'item 2', active: true ],
toggleITem = (itemName) =>
this.setState(prev =>
const nextState = prev.items.map(item =>
if (item.name !== itemName) return item;
return
...item,
active: !item.active
);
return items: nextState ;
);
render()
const items = this.state;
return (
items.map(item =>
const style = color: item.active ? 'green' : 'red' ;
return (
this.toggleITem(item.name)
style=style
>
item.name
))
);
ReactDOM.render( , document.getElementById('root'));
Un mejor enfoque sería crear una composición de componentes.
Puede crear un componente secundario que envuelva el marcado relevante, tendrá su propio controlador y obtendrá tanto el data
y handler
como apoyos de los padres.
El componente hijo invocará el controlador que obtuvo del padre y pasará el data
como parámetro.
Ejecución de ejemplo con componente hijo:
class Item extends React.Component
onClick = () =>
const onClick, name = this.props;
onClick(name);
render()
const name, active = this.props;
const style = color: active ? 'green' : 'red' ;
return (name)
class App extends React.Component
constructor(props)
super(props);
this.state =
items: [ name: 'item 1', active: false , name: 'item 2', active: true ],
toggleITem = (itemName) =>
this.setState(prev =>
const nextState = prev.items.map(item =>
if (item.name !== itemName) return item;
return
...item,
active: !item.active
);
return items: nextState ;
);
render()
const items = this.state;
return (
items.map(item =>
return
)
);
ReactDOM.render( , document.getElementById('root'));
Campos de clase el Abajo:
Como mencioné, hay un pequeño inconveniente para los campos de clase.
La diferencia entre un método de clase y un campo de clase es que el campo de clase se adjunta al instance
de El class
(función constructora).
donde los métodos y objetos de la clase se adjuntan al prototipo.
Por lo tanto, si tendrá una cantidad ridículamente grande de instancias de esta clase, mayo obtener un éxito de rendimiento.
Dado este bloque de código:
class MyClass
myMethod()
myOtherMethod = () =>
babel lo transpilará a esto:
var _createClass = function()
function defineProperties(target, props)
for (var i = 0; i < props.length; i++)
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable
return function(Constructor, protoProps, staticProps)
if (protoProps) defineProperties(Constructor.prototype, protoProps);
if (staticProps) defineProperties(Constructor, staticProps);
return Constructor;
;
();
function _classCallCheck(instance, Constructor)
if (!(instance instanceof Constructor))
throw new TypeError("Cannot call a class as a function");
var MyClass = function()
function MyClass()
_classCallCheck(this, MyClass);
this.myOtherMethod = function() ;
_createClass(MyClass, [
key: "myMethod",
value: function myMethod()
]);
return MyClass;
();
Entiendo que las funciones de flecha hacen las cosas más eficientes al no recrear las funciones de cada render de manera similar a cómo funciona el enlace en el constructor.
Esto no es true. Depende de dónde esté utilizando exactamente la función de flecha. Si Arrow function
se utilizan en el método de renderizado, luego crean una nueva instancia everytime
render se llama así como bind
trabajaría. Considere este ejemplo
this.onClick()>Previous
Aquí, cada vez que se llama renderizado, se crea una función anónima y esa función cuando se llama, llama this.onClick
.
Sin embargo, considere el caso a continuación
onClick = () =>
console.log("Div is clicked")
En el caso anterior, la función de flecha no recrea la función cada vez, sino que vincula el contexto al componente React como An arrow function does not have its own this; the this value of the enclosing execution context is used.
una vez cuando se crea una instancia de la clase. Esto es similar a como binding works is constructor
. Esto es parte de proposed class fields for arrow functions
y no es una función de ES6,
Para comprender lo que desea preguntar, debe saber que una función obtiene su contexto de donde se llama. Cheque this question
para una mayor comprensión.
En su caso, ha utilizado Arrow function
definir prevItem
y por lo tanto obtiene el contexto del componente React adjunto.
prevItem = () =>
console.log("Div is clicked")
render()
return (
)
Ahora en su hijo, incluso si llamas prevItem
con cualquier contexto personalizado, using bind or arrow function
, prevItem
cuando se ejecuta en padre, es decir Main.js
obtendrá el contexto de su componente React adjunto. Y como solo desea ejecutar la función prevItem y no desea pasar ningún dato a esto del niño, escribiendo
this.props.prevItem() />
y
this.props.onClick()>Previous
es simplemente inútil y solo aumentará la implicación del rendimiento, ya que se crean nuevas funciones en SecondClass
y ThirdClass
cada vez. Simplemente no necesita tener estas funciones definidas como función de flecha y podría simplemente escribir
y
Previous
ya que ya está enlazado en el padre.
Ahora, incluso si tiene que pasar algunos datos adicionales a estas funciones desde ThirdClass y SecondClass, no debe usar directamente Arrow function
o bind in render
. Eche un vistazo a esta respuesta en How to Avoid binding in Render method
Entonces tu primer acercamiento
this.props.prevItem() />
En esto, puede pasar cualquier argumento que esté disponible en ThirdClass a la función prevItem. Es la buena forma de llamar a funciones padre con argumentos.
this.props.prevItem(firstArgument, secondArgument) />
Tu segundo enfoque es
Este enfoque no le permite pasar ningún argumento específico de ThirdClass.
Ambos enfoques son correctos, solo eso, depende de su caso de uso. Ambos enfoques utilizan la función de flecha es6 y están a la derecha en los escenarios respectivos mencionados anteriormente