У меня следующая ситуация

export default class MyComponent extends Component { myFunc = dynamicKey ={amp}gt; { // do something with the dynamic key } render() { return ( {amp}lt;Foo{amp}gt; {amp}lt;button onClick={e ={amp}gt; this.myFunc(someDynamicKey1)} /{amp}gt; {amp}lt;button onClick={e ={amp}gt; this.myFunc(someDynamicKey2)} /{amp}gt; {amp}lt;button onClick={e ={amp}gt; this.myFunc(someDynamicKey3)} /{amp}gt; {/* ... */} {amp}lt;/Foo{amp}gt; ) } } 

Это очень распространенный случай, но он не очень хорош, потому что при каждом рендеринге он создает функцию стрелки.

В качестве обходного пути я сделал функцию, которая возвращает другую функцию с этой клавишей.

 export default class MyComponent extends Component { myFunc = dynamicKey ={amp}gt; e ={amp}gt; { // do something with the dynamic key } render() { return ( {amp}lt;Foo{amp}gt; {amp}lt;button onClick={this.myFunc(someDynamicKey1)} /{amp}gt; {amp}lt;button onClick={this.myFunc(someDynamicKey2)} /{amp}gt; {amp}lt;button onClick={this.myFunc(someDynamicKey3)} /{amp}gt; {/* ... */} {amp}lt;/Foo{amp}gt; ) } } 

Теперь я не создаю новую функцию для каждого рендера, но я вызываю новую функцию для каждого рендера.

Теперь я не уверен, какой из них использовать. Является ли вызов функции для каждого рендера плохой практикой? Должен ли я использовать функцию стрелки?

При использовании функции curried вы можете использовать ее замыкание в текущей области видимости .

 export default class MyComponent extends Component { state = { counter: 42 } myFunc = dynamicKey ={amp}gt; e ={amp}gt; { // closure on the specific this.state.counter value at time of render. } } 

Возвращая новую функцию при каждом рендере, ее закрытие находится в недавней области видимости.

 export default class MyComponent extends Component { state = { counter: 42 } myFunc = dynamicKey ={amp}gt; { // closure on this.state.counter value } } 

Следовательно, это зависит от того, какой вариант использования. Спросите себя, нужно ли функции конкретное значение или последнее.

Примечание: если при каждом рендеринге функции повторно объявляются, это становится вопросом «разницы между функцией и карри один», и для React это не имеет значения, так как оба тела функций будут выполнены. Таким образом, только запоминая функцию (не вызывайте ее с теми же параметрами), вы можете получить заметные различия.

Вы можете кэшировать ваши обработчики событий.

 class SomeComponent extends React.Component { // Each instance of SomeComponent has a cache of click handlers // that are unique to it. clickHandlers = {}; // Generate and/or return a click handler, // given a unique identifier. getClickHandler = (key) ={amp}gt; { // If no click handler exists for this unique identifier, create one. if (!this.clickHandlers[key])){ this.clickHandlers[key] = () ={amp}gt; alert(key); } return this.clickHandlers[key]; } render() { return ( {amp}lt;ul{amp}gt; {this.props.list.map(listItem ={amp}gt; {amp}lt;li key={listItem.text}{amp}gt; {amp}lt;Button onClick={this.getClickHandler(listItem.text)} /{amp}gt; {amp}lt;/li{amp}gt; )} {amp}lt;/ul{amp}gt; ); } } 

см. следующую статью

Если вы используете React-хуки, тогда:

 const Button = props ={amp}gt; { const onClick = React.useMemo(() ={amp}gt; { alert(listItem.text) }, [listItem.text]); } return {amp}lt;button onClick={onClick}{amp}gt;click{amp}lt;/button{amp}gt; } 

Если ваша функция не зависит от вашего компонента (без этого контекста), вы можете определить его вне компонента. Все экземпляры вашего компонента будут использовать одну и ту же ссылку на функцию, поскольку функция идентична во всех случаях.

В отличие от предыдущего примера, createAlertBox остается той же ссылкой на одно и то же место в памяти при каждом рендеринге. Поэтому кнопка никогда не должна перерисовываться.

Хотя Button, скорее всего, является небольшим быстрым для рендеринга компонентом, вы можете увидеть эти встроенные определения в больших, сложных, медленных для рендеринга компонентах, и это может действительно привести к зависанию вашего приложения React. Рекомендуется просто никогда не определять эти функции внутри метода рендеринга.

Если ваша функция зависит от вашего компонента, так что вы не можете определить его вне компонента, вы можете передать метод вашего компонента в качестве обработчика события:

В этом случае каждый экземпляр SomeComponent имеет различное окно предупреждения. Слушатель события click для Button должен быть уникальным для SomeComponent. Передавая метод createAlertBox, не имеет значения, будет ли SomeComponent повторно отображаться. Это даже не имеет значения, если пропадает сообщение! Адрес в памяти createAlertBox не изменяется, то есть Button не требуется повторный рендеринг, а вы экономите время обработки и повышаете скорость рендеринга вашего приложения.

Для динамических функций

В этом случае у вас есть переменное количество кнопок, создающих переменное число прослушивателей событий, каждая из которых имеет уникальную функцию, которую вы не можете знать, что происходит при создании SomeComponent. Как вы можете решить эту проблему?

Введите памятку, или, что может быть проще назвать кешированием. Для каждого уникального значения создайте и кэшируйте функцию; для всех будущих ссылок на это уникальное значение верните ранее кэшированную функцию.