Ответ 1
[ ОБНОВЛЕНИЕ: декабрь 2017]
Посмотрите официальные Документы ReactJS...
Решение этой проблемы уже хорошо документировано;)
Как передать дополнительные параметры в событие onClick с использованием синтаксиса ES6?
Например:
handleRemove = (e) => {
}
render() {
<button onClick={this.handleRemove}></button>
}
Я хочу передать id функции handleRemove
следующим образом:
<button onClick={this.handleRemove(id)}></button>
[ ОБНОВЛЕНИЕ: декабрь 2017]
Посмотрите официальные Документы ReactJS...
Решение этой проблемы уже хорошо документировано;)
Помните, что в onClick={ ... }
выражение ...
является выражением JavaScript. Так
... onClick={this.handleRemove(id)}
совпадает с
var val = this.handleRemove(id);
... onClick={val}
Другими словами, вы вызываете this.handleRemove(id)
немедленно и передаете это значение в onClick
, что не то, что вы хотите.
Вместо этого вы хотите создать новую функцию с одним из уже заполненных аргументов; по существу, вы хотите следующее:
var newFn = function() {
var args = Array.prototype.slice.call(arguments);
// args[0] contains the event object
this.handleRemove.apply(this, [id].concat(args));
}
... onClick={newFn}
Есть способ выразить это в JavaScript ES5: Function.prototype.bind
.
... onClick={this.handleRemove.bind(this, id)}
Если вы используете React.createClass
, React автоматически связывает this
для вас по методам экземпляра, и он может жаловаться, если вы не измените его на this.handleRemove.bind(null, id)
.
Вы также можете просто определить функцию inline; это сокращается с функциями стрелок, если ваша среда или транспилятор поддерживает их:
... onClick={() => this.handleRemove(id)}
Если вам нужен доступ к событию, вы можете просто передать его:
... onClick={(evt) => this.handleRemove(id, evt)}
Используйте функцию стрелки, например:
<button onClick={()=>{this.handleRemove(id)}}></button>
Используйте атрибут value элемента button для передачи идентификатора, так как
<button onClick={this.handleRemove} value={id}>Remove</button>
и затем в handleRemove прочитайте значение из события как:
handleRemove(event) {
...
remove(event.target.value);
...
}
Таким образом, вы избегаете создания новой функции (по сравнению с использованием функции стрелки) каждый раз, когда этот компонент перерисовывается.
onClick={this.handleRemove.bind(this, id)}
Что-то, о чем никто еще не упомянул, это заставить handleRemove возвращать функцию.
Вы можете сделать что-то вроде:
handleRemove = id => event => {
// Do stuff with id and event
}
// render...
return <button onClick={this.handleRemove(id)} />
Однако все эти решения имеют недостаток в создании новой функции для каждого рендеринга. Лучше создать новый компонент для Button, который получает отдельно id
и handleRemove
.
Я использую следующий код:
<Button onClick={this.onSubmit} id={item.key} value={shop.ethereum}>
Approve
</Button>
Тогда внутри метода:
onSubmit = async event => {
event.preventDefault();
event.persist();
console.log("Param passed => Eth addrs: ", event.target.value)
console.log("Param passed => id: ", event.target.id)
...
}
В следствии:
Параметр передан в событии => Eth addrs: 0x4D86c35fdC080Ce449E89C6BC058E6cc4a4D49A6
Параметр передан в событии => id: Mlz4OTBSwcgPLBzVZ7BQbwVjGip1
TL; DR:
Не связывайте функцию (и не используйте функции стрелки) внутри метода рендеринга. Смотрите официальные рекомендации.
https://reactjs.org/docs/faq-functions.html
Таким образом, есть принятый ответ и еще пара, которая указывает на то же самое. А также есть некоторые комментарии, запрещающие людям использовать bind
в методе рендеринга, а также избегают использования там функций стрелок по той же причине (эти функции будут создаваться снова и снова при каждом рендеринге). Но нет примера, поэтому я пишу один.
По сути, вы должны связать свои функции в конструкторе.
class Actions extends Component {
static propTypes = {
entity_id: PropTypes.number,
contact_id: PropTypes.number,
onReplace: PropTypes.func.isRequired,
onTransfer: PropTypes.func.isRequired
}
constructor() {
super();
this.onReplace = this.onReplace.bind(this);
this.onTransfer = this.onTransfer.bind(this);
}
onReplace() {
this.props.onReplace(this.props.entity_id, this.props.contact_id);
}
onTransfer() {
this.props.onTransfer(this.props.entity_id, this.props.contact_id);
}
render() {
return (
<div className="actions">
<button className="btn btn-circle btn-icon-only btn-default"
onClick={this.onReplace}
title="Replace">
<i className="fa fa-refresh"></i>
</button>
<button className="btn btn-circle btn-icon-only btn-default"
onClick={this.onTransfer}
title="Transfer">
<i className="fa fa-share"></i>
</button>
</div>
)
}
}
export default Actions
Ключевые строки:
конструктор
this.onReplace = this.onReplace.bind(this);
метод
onReplace() {
this.props.onReplace(this.props.entity_id, this.props.contact_id);
}
оказывать
onClick={this.onReplace}
Я использую React-Bootstrap. Триггер onSelect для выпадающих меню не позволял мне передавать данные. Просто событие. Так что помните, что вы можете просто установить любые значения в качестве атрибутов и забрать их из функции, используя JavaScript. Подбирая те атрибуты, которые вы установили в этой цели события.
let currentTarget = event.target;
let currentId = currentTarget.getAttribute('data-id');
let currentValue = currentTarget.getAttribute('data-value');