You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React点击触发事件后在另一组件渲染同一组件不同实例的实现问题

解决方案

你不需要跨组件主动获取smallView内的AbcComp实例,仅需要给fullView内的AbcComp传入和smallView内一致的btnProps属性,就能渲染出完全相同的实例效果。如果确实需要获取实例本身(比如调用实例内部方法/属性),可以配合Context做ref共享,两种场景的实现方式如下:


场景1:仅需要渲染相同样式的AbcComp(最常用,满足绝大多数需求)

  1. AbcComp.jsx 不需要修改,保持原有逻辑即可。
  2. smallViewComponent.jsx 修正原有语法错误后的代码:
import AbcComp from './..'

class SmallViewComponent extends React.Component {
  state = {
    cmpInstance: ['component1','component2','component3']
  }
  
  render (){
    return (
      <div>
        {this.state.cmpInstance.map((e) => 
          <AbcComp key={e} btnProps={e}/>  
        )}
      </div>
    )
  }
}
  1. fullViewComponent.jsx 新增state存储当前选中的实例标识,点击按钮时更新标识并传入AbcComp:
import AbcComp from './..'

// 建议把实例列表抽成公共常量,两个组件统一引入,避免重复维护
const CMP_LIST = ['component1','component2','component3']

class FullViewComponent extends React.Component {
  state = {
    currentCmpKey: null
  }

  loadInstance = () => {
    const selectedKey = CMP_LIST[Math.floor(Math.random() * CMP_LIST.length)]
    this.setState({ currentCmpKey: selectedKey })
  }

  render (){ 
    return (
      <div>
        <button onClick={this.loadInstance}>切换实例</button>
        {/* 传入选中的标识即可渲染对应样式的AbcComp */}
        {this.state.currentCmpKey && <AbcComp btnProps={this.state.currentCmpKey} />}
      </div>
    )
  }
}

场景2:需要获取AbcComp的实例对象(调用实例内部方法/属性)

如果需要拿到实例本身,通过React Context共享ref即可:

  1. 新增公共Context文件CmpContext.js:
import { createContext } from 'react'
export const CmpContext = createContext()
  1. 在两个组件的公共父组件内注入Context,统一存储所有实例ref:
import { CmpContext } from './CmpContext'
import SmallViewComponent from './smallViewComponent'
import FullViewComponent from './fullViewComponent'

class ParentComponent extends React.Component {
  state = {
    cmpRefs: {}
  }

  saveCmpRef = (key, ref) => {
    this.setState(prev => ({
      cmpRefs: { ...prev.cmpRefs, [key]: ref }
    }))
  }

  render() {
    return (
      <CmpContext.Provider value={{ 
        cmpRefs: this.state.cmpRefs, 
        saveCmpRef: this.saveCmpRef 
      }}>
        <SmallViewComponent />
        <FullViewComponent />
      </CmpContext.Provider>
    )
  }
}
  1. 修改smallViewComponent.jsx,给每个AbcComp挂载ref并存入Context:
import AbcComp from './..'
import { CmpContext } from './CmpContext'

const CMP_LIST = ['component1','component2','component3']

class SmallViewComponent extends React.Component {
  static contextType = CmpContext

  render (){
    return (
      <div>
        {CMP_LIST.map((e) => 
          <AbcComp 
            key={e} 
            btnProps={e}
            ref={(ref) => this.context.saveCmpRef(e, ref)}
          />  
        )}
      </div>
    )
  }
}
  1. 修改fullViewComponent.jsx,点击按钮时即可从Context中获取对应实例:
import AbcComp from './..'
import { CmpContext } from './CmpContext'

const CMP_LIST = ['component1','component2','component3']

class FullViewComponent extends React.Component {
  static contextType = CmpContext
  state = {
    currentCmpKey: null
  }

  loadInstance = () => {
    const selectedKey = CMP_LIST[Math.floor(Math.random() * CMP_LIST.length)]
    this.setState({ currentCmpKey: selectedKey })
    // 这里可以拿到smallView中对应的AbcComp实例
    const targetInstance = this.context.cmpRefs[selectedKey]
    console.log('获取到的实例:', targetInstance)
  }

  render (){ 
    return (
      <div>
        <button onClick={this.loadInstance}>切换实例</button>
        {this.state.currentCmpKey && <AbcComp btnProps={this.state.currentCmpKey} />}
      </div>
    )
  }
}

内容的提问来源于stack exchange,提问作者Ahmad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 13:24:05