如何从对象中的组件访问道具

Posted

技术标签:

【中文标题】如何从对象中的组件访问道具【英文标题】:how to get access to a prop from component in an Object 【发布时间】:2020-10-12 07:02:50 【问题描述】:

我必须检查我网站的当前路径名,以便为我的 React-Joyride 导览设置步骤。

我有一个父组件,其中定义了路线并实现了 Joyride 游览。 Tutorial 组件实现了 step 对象来设置游览的步骤,如下所示:

import Tutorial from './tutorial/tutorial'
class App extends Component 
 constructor (props) 
    super(props)
    this.state= 
    // state things 
    
 
  render () 
    return ( 
    <BrowserRouter>
        <Tutorial
          run=this.state.run
          stepIndex=this.state.stepIndex
          firstPartClicked=this.state.firstPartClicked
          secondPartClicked=this.state.secondPartClicked
          handleRestart=this.handleRestart
          handleEnd=this.handleEnd
          handleSteps=this.handleSteps
          handleFirstPart=this.handleFirstPart
          handleSecondPart=this.handleSecondPart
          handleClickedFalse=this.handleClickedFalse
          handleSetVisited=this.handleSetVisited
          handleCheckTourDone=this.handleCheckTourDone
        />
        // many other Routes 
        <Route
            exact path='/matches/:matchId/' render=(props) => 
              this.removeGlobalTimeRef()
              const matchId = this.props.matchId
              return this.checkLoginThen(this.gotoMatchDetails(props))
            
          />
    </BrowserRouter>
    )
  

    
export default App  



import matchSteps from '../tutorial/steps/matchSteps'
class Tutorial extends React.Component 
  constructor (props) 
    super(props)
    this.state = 
      isUpdatet: false,
      steps: []
    
  
  
  callback = (tour) => 
    const  action, index, type, status  = tour

    if ([STATUS.FINISHED].includes(status)) 
      this.props.handleEnd()
      this.props.handleClickedFalse()
      if (this.props.location.pathname.startsWith('/matches/') && this.props.location.pathname.includes('sequence')) 
        this.props.handleSetVisited()
      
     else if ([STATUS.SKIPPED].includes(status)) 
      this.props.handleEnd()
      this.props.handleClickedFalse()
      this.props.handleSetVisited()
     else if (action === 'close') 
      this.props.handleEnd()
      this.props.handleClickedFalse()
     else if ([EVENTS.STEP_AFTER, EVENTS.TARGET_NOT_FOUND].includes(type)) 
      const step = index + (action === ACTIONS.PREV ? -1 : 1)
      this.props.handleSteps(step)
    
  
  
  render () 
    let  steps  = this.state
    const pathname = this.props.location.pathname
    const siteSteps = [matchSteps, matchEditorSteps, matchEditorStepsOne, matchEditorStepsTwo,
      matchSequenceSteps, matchSequenceStepsOne, matchSequenceStepsTwo, matchSiteSteps, matchSiteStepsOne, matchSiteStepsTwo]

    for (let i = 0; i < siteSteps.length; i++) 
      if (pathname === siteSteps[i].onSite && siteSteps[i].part === 'full') 
        steps = siteSteps[i].steps
       else if (pathname === siteSteps[i].onSite && siteSteps[i].part === 'one') 
        if (this.props.firstPartClicked === true) 
          steps = siteSteps[i].steps
        
       else if (pathname === siteSteps[i].onSite && siteSteps[i].part === 'two') 
        if (this.props.secondPartClicked === true) 
          steps = siteSteps[i].steps
        
      
    
   
   return (
      <>
        <Joyride
          callback=this.callback
          run=this.props.run
          stepIndex=this.props.stepIndex
          steps=steps
          continuous
          disableOverlayClose
          spotlightClicks
          showSkipButton
          locale=
            back: <span>Zurück</span>,
            last: (<span>Beenden</span>),
            next: (<span>Weiter</span>)
          
          styles=
            options: 
              primaryColor: '#2d98da'
            
          
        />
      </>
    )


export default withRouter(Tutorial)



const matchSteps = 
  name: 'matchSteps',
  // onSite: '/matches/:matchId/',   <-- HERE 
  part: 'full',
  steps: [
    target: '.row',
    title: '',
    content: 'bla bla',
    placement: 'center',
    disableBeacon: true
  ]
  
export default matchSteps

现在我必须在步骤对象中将 matchId 设置为 onSite: '/matches/:matchId/',以便我可以检查教程组件中的路径名。 我不知道如何正确执行我已经测试了一些想法,但 matchId 始终未定义。

【问题讨论】:

【参考方案1】:

可以使用react router hooksuseParams获取当前url的参数

import  useParams  from "react-router-dom";

let  slug  = useParams();

或者使用 react router hooks useLocation 获取当前 url 为 location 对象

import  useLocation  from "react-router-dom";

let location = useLocation();

【讨论】:

谢谢,但是 matchId 总是不同的,具体取决于选择的游戏。我必须检查当前路径名是否与 onSite 属性匹配。 我不明白但是,你能解释一下吗?什么不适合? 我会尝试,matchsteps 是一个对象,它在教程组件中用于呈现页面(onSite)的正确步骤。我需要来自父组件的 matchId 来在我的匹配步骤中声明 onSite 路径。如果 onSite === 路径名,我可以检查教程组件。我不知道是否有更好的方法。我是反应和编程方面的新手【参考方案2】:

我不清楚你的问题。好吧,问题很清楚,但代码 sn-ps 不是。

javascript 中只有两个数据流。数据通过属性从父级流向子级。数据可以通过回调传递回父级。您可以从孩子 -> 父母 -> 祖父母链接该回调。

class grandparent extends Component 
   getDecentData = (data) =>  do something with data

   render()
        <Parent CB = this.getDecentData/>
    


class Parent extends Component 

   render()
        <Child CB = this.props.CB />
    


class Child extends Component 

    clickHandler=(e) => 
       // do something to get data
       this.props.CB(data)
    

   render()
          <Control  onClick=this.clickHandler />
    

【讨论】:

我将它用于我的函数以通过组件传递它们,但 matchSteps 是一个对象而不是一个组件,所以我不知道如何访问 matchId 很难遵循所有代码,如果将其修剪为有问题的变量会更好。但我认为你的基本方法是错误的,使用一个设置变量来回调组件的函数。匹配步骤从哪里获取 matchId? 目前 matchsteps 没有得到 matchid 那是我的问题,我必须访问 matchsteps 对象中的 match id 在渲染需要此值的组件时,此 matchId 是否存在于 url 中?

以上是关于如何从对象中的组件访问道具的主要内容,如果未能解决你的问题,请参考以下文章

如何将 ref 作为组件对象中的道具传递?

从 Vue 组件中的对象道具初始化数据

如何将道具从组件传递到 NextJS 中的 getServerSideProps()?

如何访问react组件中的url参数

如何将从数据库接收到的数据作为道具传递给 Reactjs 中的另一个组件

如何更新故事书中的组件道具