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

时间:2020-06-22 12:07:11

标签: javascript reactjs react-router components react-props

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

我有一个上级组件,其中定义了路线,并在其中实现了Joyride漫游。 教程组件实现了“步骤对象”来设置游览步骤,如下所示:

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

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

2 个答案:

答案 0 :(得分:0)

您可以使用react router钩子Array.reduce来获取当前网址的参数

import { useParams } from "react-router-dom";

let { slug } = useParams();

或使用react router钩子useParams来获取当前的URL作为useLocation对象

import { useLocation } from "react-router-dom";

let location = useLocation();

答案 1 :(得分:0)

我不清楚您的问题。好了,问题很明显,但是代码段却不清楚。

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} />
    }
}