Reactjs 如何在 map 函数中使用 ref?
Reactjs how to use ref inside map function?
我正在通过一个数组进行映射,并为每个项目显示一个带有文本的按钮。假设我希望在单击按钮时,下面的文本会将其颜色更改为红色。我如何定位按钮的同级?我尝试使用 ref 但由于它是映射的 jsx,因此只会声明最后一个 ref 元素。
这是我的代码:
class Exams extends React.Component {
constructor(props) {
super()
this.accordionContent = null;
}
state = {
examsNames: null, // fetched from a server
}
accordionToggle = () => {
this.accordionContent.style.color = 'red'
}
render() {
return (
<div className="container">
{this.state.examsNames && this.state.examsNames.map((inst, key) => (
<React.Fragment key={key}>
<button onClick={this.accordionToggle} className="inst-link"></button>
<div ref={accordionContent => this.accordionContent = accordionContent} className="accordionContent">
<p>Lorem ipsum dolor sit amet consectetur, adipisicing elit. Aperiam, neque.</p>
</div>
</React.Fragment>
))}
</div>
)
}
}
export default Exams;
如前所述,结果是每次单击按钮时,最后一个按钮所附的段落将被定位。
提前致谢
初始化this.accordionContent
为数组
constructor(props) {
super()
this.accordionContent =[];
}
然后像这样设置 ref
<div ref={accordionContent => this.accordionContent[key] = accordionContent} className="accordionContent">
我找到了一种不使用 ref 的方法,方法是使用地图的键 属性:
accordionToggle = (key) => {
console.log(key)
var a = document.getElementsByClassName('accordionContent')
a[key].style.color = 'red'
}
我不确定像这样访问 dom 与使用 refs 直接定位元素是否一样好。
这是我基于您上面的代码的工作代码笔示例
链接示例是 "actual" 手风琴,即显示和隐藏相邻内容。
(请参阅下面的代码片段以了解如何变为红色)
https://codepen.io/PapaCodio/pen/XwxmvK?editors=0010
代码片段
初始化引用数组:
constructor(props) {
super();
this.accordionContent = [];
}
使用键将 ref 添加到引用数组:
<div ref={ref => (this.accordionContent[key] = ref)} >
通过onClick将key传递给toggle函数
<button onClick={() => this.accordionToggle(key)} >
终于引用了切换函数中的键
accordionToggle = key => {
this.accordionContent[key].style.color = 'red'
};
在下面的示例中,我使用了一个 refs
数组,使用 useRef
进行了初始化,以便在重新渲染时保持持久性,然后在第一次渲染时填充 <Wrapper>
,并且从那时起,所有在 map
中使用 React.createRef()
创建的引用都将缓存在 refs
中,并在 <Wrapper>
重新渲染时准备好使用。
每个动态 ref
(属于 refs
数组)作为 prop 分配给每个子节点:
const Wrapper = ({children}) => {
const refs = React.useRef([]);
// as the refs are assigned with `ref`, set each with a color "red"
React.useEffect(() => {
refs.current.map(ref => {
// no support here for optional chaining: ref?.current?.style.color
if(ref.current) ref.current.style.color = 'red'
})
}, [refs]);
// iterate the children and create a ref inide the "refs" array,
// if one was not already added for this child's index.
// use "cloneElement" to pass that ref to the children
const withProps = React.Children.map(children, (child, i) => {
// no support here for ?? instead of ||
refs.current[i] = refs.current[i] || React.createRef();
return React.cloneElement(child, {ref: refs.current[i] })
});
// no support for <> instead of useless `div` wrapper
return <div>{withProps}</div>
};
ReactDOM.render(<Wrapper>
<button>1</button>
<button>2</button>
<button>3</button>
</Wrapper>, document.body)
<script crossorigin src="https://unpkg.com/react@17/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.production.min.js"></script>
我正在通过一个数组进行映射,并为每个项目显示一个带有文本的按钮。假设我希望在单击按钮时,下面的文本会将其颜色更改为红色。我如何定位按钮的同级?我尝试使用 ref 但由于它是映射的 jsx,因此只会声明最后一个 ref 元素。
这是我的代码:
class Exams extends React.Component {
constructor(props) {
super()
this.accordionContent = null;
}
state = {
examsNames: null, // fetched from a server
}
accordionToggle = () => {
this.accordionContent.style.color = 'red'
}
render() {
return (
<div className="container">
{this.state.examsNames && this.state.examsNames.map((inst, key) => (
<React.Fragment key={key}>
<button onClick={this.accordionToggle} className="inst-link"></button>
<div ref={accordionContent => this.accordionContent = accordionContent} className="accordionContent">
<p>Lorem ipsum dolor sit amet consectetur, adipisicing elit. Aperiam, neque.</p>
</div>
</React.Fragment>
))}
</div>
)
}
}
export default Exams;
如前所述,结果是每次单击按钮时,最后一个按钮所附的段落将被定位。
提前致谢
初始化this.accordionContent
为数组
constructor(props) {
super()
this.accordionContent =[];
}
然后像这样设置 ref
<div ref={accordionContent => this.accordionContent[key] = accordionContent} className="accordionContent">
我找到了一种不使用 ref 的方法,方法是使用地图的键 属性:
accordionToggle = (key) => {
console.log(key)
var a = document.getElementsByClassName('accordionContent')
a[key].style.color = 'red'
}
我不确定像这样访问 dom 与使用 refs 直接定位元素是否一样好。
这是我基于您上面的代码的工作代码笔示例
链接示例是 "actual" 手风琴,即显示和隐藏相邻内容。
(请参阅下面的代码片段以了解如何变为红色)
https://codepen.io/PapaCodio/pen/XwxmvK?editors=0010
代码片段
初始化引用数组:
constructor(props) {
super();
this.accordionContent = [];
}
使用键将 ref 添加到引用数组:
<div ref={ref => (this.accordionContent[key] = ref)} >
通过onClick将key传递给toggle函数
<button onClick={() => this.accordionToggle(key)} >
终于引用了切换函数中的键
accordionToggle = key => {
this.accordionContent[key].style.color = 'red'
};
在下面的示例中,我使用了一个 refs
数组,使用 useRef
进行了初始化,以便在重新渲染时保持持久性,然后在第一次渲染时填充 <Wrapper>
,并且从那时起,所有在 map
中使用 React.createRef()
创建的引用都将缓存在 refs
中,并在 <Wrapper>
重新渲染时准备好使用。
每个动态 ref
(属于 refs
数组)作为 prop 分配给每个子节点:
const Wrapper = ({children}) => {
const refs = React.useRef([]);
// as the refs are assigned with `ref`, set each with a color "red"
React.useEffect(() => {
refs.current.map(ref => {
// no support here for optional chaining: ref?.current?.style.color
if(ref.current) ref.current.style.color = 'red'
})
}, [refs]);
// iterate the children and create a ref inide the "refs" array,
// if one was not already added for this child's index.
// use "cloneElement" to pass that ref to the children
const withProps = React.Children.map(children, (child, i) => {
// no support here for ?? instead of ||
refs.current[i] = refs.current[i] || React.createRef();
return React.cloneElement(child, {ref: refs.current[i] })
});
// no support for <> instead of useless `div` wrapper
return <div>{withProps}</div>
};
ReactDOM.render(<Wrapper>
<button>1</button>
<button>2</button>
<button>3</button>
</Wrapper>, document.body)
<script crossorigin src="https://unpkg.com/react@17/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.production.min.js"></script>