передать реквизит с функциональным компонентом без объявления функции внутри компонента - PullRequest
0 голосов
/ 04 декабря 2018

Я перебираю список элементов и хочу вызвать функцию onClick ().Пример ниже:

class App extends Component {
    state = { items: [1, 2, 3, 4] };

    click = i => console.log(i);

    render() {
        return (
            <div>
                {this.state.items.map(item => (
                    <div 
                        key={item} 
                        // this works fine, but I rather not declare functions within the render function / JSX
                        onClick={() => this.click(item)}
                    >
                        {`click on # ${item}`}
                    </div>
                ))}
            </div>
        )
    }
}

Как видите, я объявляю функцию в JSX.Я делаю это снова и снова, но некоторое время назад я узнал, что вам следует избегать объявления функции внутри самого компонента JSX по соображениям производительности.

Это верно и для функциональных компонентов?И если да, есть ли другой способ передать динамическую информацию (в данном случае элемент) в обратный вызов?

ПРИМЕЧАНИЕ. Я с нетерпением жду возможности использовать ловушки в какой-то момент, но сейчас я просто хочузнать лучшие практики, не используя их.

ПРИМЕЧАНИЕ II: При этом, если вы уверены, что это актуальная проблема и до сих пор ее не удалось решить из-за хуков, я, очевидно, хотел бы изучитьчто:)

Ответы [ 3 ]

0 голосов
/ 04 декабря 2018

Это правда и для функциональных компонентов?

Ну, на самом деле в вашем коде нет функционального компонента.И все, что вы делаете в функции, которая вызывается очень часто (например, render()), приводит к снижению производительности, независимо от того, является ли это функцией или объявлением или вызовом переменной.Другое дело, что это уменьшение имеет значение.

И если да, есть ли другой способ передать динамическую информацию (в данном случае элемент) в обратный вызов?

Вы могли бы .bind(...) это:

 onClick = {console.log.bind(console, item) }

но на самом деле, вы заметили какую-либо задержку при повторном рендеринге?Вероятно, нет, и если так, то это не вызвано объявлением функции.Пишите код, который выглядит красиво для вас, не оптимизируйте его для компилятора, пусть компилятор сделает это.

, но некоторое время назад я узнал, что вам следует избегать объявления функции внутри самого компонента JSX

Тебе не стоит этого избегать, предпочтительнее, если возможно, другие способы.В этом случае нет лучшего способа, так что иди с ним.

0 голосов
/ 04 декабря 2018

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

Затем внутри дочернего компонента вы можете легко ссылаться на обработчик как this.props.onClick

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

class Parent extends Component {
    state = { items: [1, 2, 3, 4] };

    parentClick(item) {
        // do something
        console.log(item);
    }
    render() {
        return (
            <div>
                {this.state.items.map(item => (
                  <Child item={item} onClick={this.parentClick}>
                ))}
            </div>
        )
    }
}



class Child extends Component {

    childClick(item) {
        this.props.onClick(item)
    }

    render() {
        return (
            <div>
                <p onClick={this.childClick(this.props.item)}>this.props.item</p>
            </div>
        )
    }
}
0 голосов
/ 04 декабря 2018

Вы можете объявить другой метод, подобный этому.Не забудьте использовать .bind.В противном случае метод не будет вызван правильно.

class App extends Component {
    state = { items: [1, 2, 3, 4] };

    handleClick(item) {
        // do something
        console.log(item);
    }
    render() {
        return (
            <div>
                {this.state.items.map(item => (
                    <div 
                        key={item} 
                        // this works fine, but I rather not declare functions within the render function / JSX
                        onClick={this.handleClick.bind(this, item)}
                    >
                        {`click on # ${item}`}
                    </div>
                ))}
            </div>
        )
    }
}
...