【问题标题】: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 始终未定义。

【问题讨论】:

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


    【解决方案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 中?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-11
    • 2022-09-28
    • 2021-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多