【问题标题】:Reactjs how to use ref inside map function?Reactjs如何在map函数中使用ref?
【发布时间】:2019-06-16 07:37:07
【问题描述】:

我正在通过一个数组进行映射,并为每个项目显示一个带有文本的按钮。假设我希望在单击按钮时,下面的文本将其颜色变为红色。如何定位按钮的兄弟姐妹?我尝试使用 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;

如上所述,结果是每次单击按钮时,附加到最后一个按钮的段落将成为目标。

提前致谢

【问题讨论】:

标签: css reactjs ref


【解决方案1】:

this.accordionContent初始化为数组

constructor(props) {
    super()
    this.accordionContent =[];
}

并像这样设置ref

<div ref={accordionContent => this.accordionContent[key] = accordionContent} className="accordionContent">

【讨论】:

  • 我还找到了另一种方法,我不确定它是否一样好,但我会在这里发布
【解决方案2】:

这是我的工作代码笔示例,基于您上面的代码

链接示例是“实际”手风琴,即显示和隐藏相邻内容。

(变红见下方代码sn-ps)

https://codepen.io/PapaCodio/pen/XwxmvK?editors=0010


代码片段

初始化引用数组:

constructor(props) {
    super();
    this.accordionContent = [];
}

使用 key 将 ref 添加到引用数组中:

<div ref={ref => (this.accordionContent[key] = ref)} >

通过 onClick 将键传递给切换功能

 <button onClick={() => this.accordionToggle(key)} >

终于引用了toggle函数里面的key

accordionToggle = key => {
    this.accordionContent[key].style.color = 'red'
};

【讨论】:

    【解决方案3】:

    我找到了一种不使用 ref 的方法,通过使用 map 的 key 属性:

     accordionToggle = (key) => {
            console.log(key)
            var a = document.getElementsByClassName('accordionContent')
            a[key].style.color = 'red'
        }
    

    我不确定像这样访问 dom 是否一样好,而不是使用 refs 直接定位元素。

    【讨论】:

      【解决方案4】:

      在下面的示例中,我使用refs 数组,使用useRef 初始化,用于在重新渲染之间保持持久性,然后在第一次渲染&lt;Wrapper&gt; 时填充,然后从那时起,所有引用创建在map 中使用React.createRef() 将被缓存在refs 中,并且可以在&lt;Wrapper&gt; 重新渲染时使用。

      每个动态refrefs 数组)都作为道具分配给每个子节点:

      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>

      【讨论】:

        猜你喜欢
        • 2018-02-04
        • 2022-01-15
        • 2020-03-06
        • 1970-01-01
        • 2021-01-30
        • 1970-01-01
        • 1970-01-01
        • 2021-10-17
        • 1970-01-01
        相关资源
        最近更新 更多