2015-08-28 12 views
28

Sto lavorando a un'applicazione di reazione utilizzando il router di risposta. Ho una pagina progetto che ha un URL come segue:Il componente non si rimonta quando i parametri del percorso cambiano

myapplication.com/project/unique-project-id 

Quando i carichi componente del progetto, ho innescano una richiesta di dati per quel progetto dall'evento componentDidMount. Ora sto correndo in un problema in cui, se posso passare direttamente tra due progetti in modo che solo i cambiamenti id come questo ...

myapplication.com/project/982378632 
myapplication.com/project/782387223 
myapplication.com/project/198731289 

componentDidMount non viene attivato di nuovo in modo che i dati non viene aggiornata. C'è un altro evento del ciclo di vita che dovrei usare per attivare la mia richiesta di dati o una strategia diversa per affrontare questo problema?

+1

Potrebbe pubblicare il codice dei componenti? – Pcriulan

risposta

33

Se il collegamento è diretto allo stesso percorso con solo un parametro diverso, non sta rimontando, ma invece riceve nuovi oggetti di scena. Pertanto, è possibile utilizzare la funzione componentWillReceiveProps(newProps) e cercare newProps.params.projectId.

Se si sta tentando di caricare i dati, si consiglia di recuperare i dati prima che il router gestisca la corrispondenza utilizzando metodi statici sul componente. Guarda questo esempio. React Router Mega Demo. In questo modo, il componente caricherà i dati e si aggiornerà automaticamente quando i parametri del percorso cambiano senza dover contare su componentWillReceiveProps.

+0

Grazie. Sono stato in grado di farlo funzionare usando componentWillReceiveProps. Ancora non capisco il flusso di dati di Mega Demo di React Router. Vedo il static fetchData definito su alcuni componenti. Come vengono richiamate queste statiche dal lato client del router? – Constellates

+0

Ottima domanda. Controlla il file client.js e il file server.js. Durante il runcycle del router chiamano il file fetchData.js e passano lo 'state' ad esso. All'inizio è un po 'confuso, ma poi diventa un po' più chiaro. –

+0

Venendo a questo alcuni mesi più tardi, ed essendo molto inesperto, sto avendo difficoltà ad aggiornare gli esempi con le modifiche a react-router con rilascio di 1.0 - è ancora possibile ora che Router.run è stato sostituito con render ( {routes }}, el) - possiamo ancora eseguire il recupero prima che il router gestisca la corrispondenza? – theTechnaddict

21

Se è necessario rimontare un componente quando il percorso viene modificato, è possibile passare una chiave univoca all'attributo chiave del componente (la chiave è associata al percorso/alla rotta). Quindi, ogni volta che la rotta cambia, la chiave cambierà anche i trigger del componente React da smontare/rimontare. Ho ricevuto l'idea da this answer

+0

questo è assolutamente fantastico, grazie! – davnicwil

+0

Grazie. Questa dovrebbe essere accettata risposta –

0

react-router è danneggiato perché è necessario rimontare i componenti in qualsiasi posizione.

sono riuscito a trovare una correzione per questo problema però:

https://github.com/ReactTraining/react-router/issues/1982#issuecomment-275346314

In breve (si veda il link qui sopra per la piena informazioni)

<Router createElement={ (component, props) => 
{ 
    const { location } = props 
    const key = `${location.pathname}${location.search}` 
    props = { ...props, key } 
    return React.createElement(component, props) 
} }/> 

In questo modo sarà rimontare su qualsiasi URL cambia

4

Devi essere chiaro, che un cambio di percorso non causerà un aggiornamento della pagina, devi gestirlo da solo.

import theThingsYouNeed from './whereYouFindThem' 

export default class Project extends React.Component { 

    componentWillMount() { 

     this.state = { 
      id: this.props.router.params.id 
     } 

     // fire action to update redux project store 
     this.props.dispatch(fetchProject(this.props.router.params.id)) 
    } 

    componentDidUpdate(prevProps, prevState) { 
     /** 
     * this is the initial render 
     * without a previous prop change 
     */ 
     if(prevProps == undefined) { 
      return false 
     } 

     /** 
     * new Project in town ? 
     */ 
     if (this.state.id != this.props.router.params.id) { 
      this.props.dispatch(fetchProject(this.props.router.params.id)) 
      this.setState({id: this.props.router.params.id}) 
     } 

    } 

    render() { <Project .../> } 
} 
+0

Grazie, questa soluzione funziona per me. Ma il mio ambiente eslint si sta lamentando di questo: https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-did-update-set-state.md Cosa ne pensi Questo? – Konekoya

+0

Sì, in realtà non è la cosa migliore, mi dispiace, dopo aver inviato il "fetchProject" il tuo riduttore aggiornerà comunque i tuoi oggetti di scena, l'ho usato per fare il mio punto senza rimettere a posto – chickenchilli

+0

Ciao chickenchilli, In realtà sono ancora bloccato in questo ... hai altri suggerimenti o tutorial consigliati? O rimarrò alla tua soluzione per ora. Grazie per l'aiuto! – Konekoya

Problemi correlati