[英]How to assign refs to multiple components
我正在使用React使用array.map
渲染多個數據。
如何禁用列表中的單擊按鈕?
這是我的代碼:
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>
);
}
}
使用refs
無效...我認為我無法添加狀態,因為有多個按鈕。
您應該使用ref callback
而不是ref,而且是的,您需要多個ref,一個數組應該很好
根據文檔:
React支持一個可以附加到任何組件的特殊屬性。 ref屬性具有
callback
函數,在掛載或卸載組件之后,將立即執行該callback
。在HTML元素上使用ref屬性時,
ref callback
接收基礎DOM元素作為其參數。
ref callbacks
在componentDidMount
或componentDidUpdate
生命周期掛鈎之前被調用。僅使用ref回調在類上設置屬性是訪問DOM元素的常見模式。 首選方法是像上面的示例一樣在ref回調中設置屬性。 甚至還有一種更短的編寫方法:
ref={input => this.textInput = input}.
字符串引用是舊版,並且根據docs :
舊版API:字符串引用
如果您之前使用過React,那么您可能會熟悉一個較舊的API,其中ref屬性是一個字符串,例如“ textInput”,並且DOM節點可以通過
this.refs.textInput
訪問。 我們建議不要這樣做,因為字符串引用存在一些問題,被認為是舊問題,並且很可能在將來的發行版中刪除。 如果您當前正在使用this.refs.textInput
訪問refs
,則建議改用回調模式。
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={(ref) => this.btn[index] = ref} onClick={boundActRunClick}>Run</button>
</p>
)
})
}
</div>
);
}
像@ShubhamKhatri的使用ref
的答案是一個選項。 您也可以通過狀態來實現所需的行為。
示例 (單個禁用按鈕選項)
class App extends Component{
constructor() {
super();
this.state = {
disabled: ''
};
}
onRunClick(act, index, e) {
this.setState({ disabled: act._id });
}
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 disabled={this.state.disabled === act._id} onClick={boundActRunClick}>Run</button>
</p>
)
})
}
</div>
);
}
}
示例 (多個禁用按鈕選項)
class App extends Component{
constructor() {
super();
this.state = {
buttons: {}
};
}
onRunClick(act, index, e) {
this.setState((prevState) => {
const buttons = Object.assign({}, prevState.buttons, { [act._id]: !prevState.buttons[act._id] });
return { buttons };
});
}
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 disabled={this.state.buttons[act._id] || false} onClick={boundActRunClick}>Run</button>
</p>
)
})
}
</div>
);
}
}
您可以使用npm模塊react-multi-ref (我的一個小庫)來執行此操作。
import React from 'react';
import MultiRef from 'react-multi-ref';
class Foo extends React.Component {
_actRefs = new MultiRef();
onRunClick(act, e) {
this._actRefs.map.get(act._id).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={this._actRefs.ref(act._id)} onClick={boundActRunClick}>Run</button>
</p>
)
})
}
</div>
);
}
}
盡管在這種特定情況下,您只想更改元素的屬性,而不是使用ref,您應該通過React通過<button>
上的state和props來實現它,就像@bennygenel的回答一樣 。 但是,如果您需要做其他事情(在按鈕上調用命令式DOM方法,讀取不受控制的輸入元素的值,讀取元素的屏幕位置等),則需要使用這樣的ref。
對於功能組件(React 16+),您可以按以下方式進行處理:
/*
* @param {Object|Function} forwardedRef callback ref function or ref object that `refToAssign` will be assigned to
* @param {Object} refToAssign React ref object
*/
export function assignForwardedRefs(forwardedRef, refToAssign) {
if (forwardedRef) {
if (typeof forwardedRef === 'function') {
forwardedRef(refToAssign)
} else {
forwardedRef.current = refToAssign
}
}
}
function MyComponent({
forwardedRef
}) {
const innerRef = useRef()
function setRef(ref) {
assignForwardedRefs(forwardedRef, ref)
innerRef.current = ref
}
return <div ref={setRef}>Hello World!</div>
}
export default React.forwardRef((props, ref) => <MyComponent {...props} forwardedRef={ref} />)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.