Friday, May 17, 2024
 Popular · Latest · Hot · Upcoming
140
rated 0 times [  145] [ 5]  / answers: 1 / hits: 70200  / 7 Years ago, wed, november 1, 2017, 12:00:00

I'm using React to render multiple data using array.map.

How can disable the clicked button from the list?



This is my code:



  onRunClick(act, e) {
this.refs.btn.setAttribute(disabled, true);
}

render () {
return (
<div>
{
this.state.acts.map((act) => {
let boundActRunClick = this.onRunClick.bind(this, act);

return (
<p key={act._id}>
Name: {act.name}, URL(s): {act.urls}
<button ref='btn' onClick={boundActRunClick}>Run</button>
</p>
)
})
}
</div>
);
}
}


Using refs doesn't work ... I think that I can't add a state since there are multiple buttons.


More From » reactjs

 Answers
19

You should use ref callback instead of ref and also yes you need multiple refs, an array should be good


According to the docs:



React supports a special attribute that you can attach to any
component. The ref attribute takes a callback function, and the
callback will be executed immediately after the component is mounted
or unmounted.


When the ref attribute is used on an HTML element, the ref callback
receives the underlying DOM element as its argument.


ref callbacks are invoked before componentDidMount or
componentDidUpdate lifecycle hooks.


Using the ref callback just to set a property on the class is a common
pattern for accessing DOM elements. The preferred way is to set the
property in the ref callback like in the above example. There is even
a shorter way to write it: ref={input => this.textInput = input}.



String refs are a legacy and and as per the docs:


Legacy API: String Refs



If you worked with React before, you might be familiar with an older
API where the ref attribute is a string, like "textInput", and the DOM
node is accessed as this.refs.textInput. We advise against it
because string refs have some issues, are considered legacy, and are
likely to be removed in one of the future releases. If you’re
currently using this.refs.textInput to access refs, we recommend
the callback pattern instead.



constructor() {
super();
this.btn = [];
}
onRunClick(act, index, e) {
this.btn[index].setAttribute("disabled", true);
}

render () {
return (
<div>
{
this.state.acts.map((act, index) => {
let boundActRunClick = this.onRunClick.bind(this, act, index);

return (
<p key={act._id}>
Name: {act.name}, URL(s): {act.urls}
<button ref={(el) => this.btn[index] = el} onClick={boundActRunClick}>Run</button>
</p>
)
})
}
</div>
);
}

[#56047] Sunday, October 29, 2017, 7 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
victorr

Total Points: 193
Total Questions: 86
Total Answers: 105

Location: Pitcairn Islands
Member since Thu, Jun 24, 2021
3 Years ago
;