2017-07-07 2 views
2

Ich habe ein ReactJS-Projekt, wo ich JSON vom REST Django-Host bekomme und eine Tabelle mit Filtern dafür erstelle. Ich habe eine Tabellenklasse:Wie man eine Komponente nur einbaut, wenn ich die Klasse reps ändere

class MainTable extends React.Component { 

    constructor(props) { 
    super(props); 
    this.state = { 
     results: [] 
    }; 
    } 

    componentDidMount(){ 
    axios.get(this.props.link) 
     .then(res => { 
     this.setState({results: res.data.results}); 
    }); 
    } 

    render() { 
    return (
     <Table hover striped bordered responsive size="sm"> 
     <thead> 
      <tr> 
      <th>Name</th> 
      <th>Name</th> 
      </tr> 
     </thead> 
     <tbody> 
      {this.state.results.map(result => 
      <tr key={result.fileId}> 
       <td>{result.Name}</td> 
       <td>{result.Name}</td> 
      </tr> 
     )} 
     </tbody> 
     </Table> 
    ); 
    } 
} 

und Main, wo ich alle Filterklassen laufen:

class Main extends React.Component { 
    constructor() { 
    super(); 
    this.state = { 
     origin: '', 
     limit: 10 
    }; 

    this.handleChangeOrigin = this.handleChangeOrigin.bind(this); 
    this.handleChangeLimit = this.handleChangeLimit.bind(this); 
    } 

    handleChangeLimit(event) { 
    this.setState({limit: event.target.value}); 
    } 
    handleChangeOrigin(event) { 
    this.setState({origin: event.target.value}); 
    } 

    render() { 
    var link = `http://106.120.89.142:8000/database/?limit=${this.state.limit}&`; 
    if (this.state.origin){ 
     link += `ORIGIN=${this.state.origin.toLowerCase()}`; 
     console.log(link) 
    } 
    return (
     <div> 
     <div> 
      <h1 className="jumbotron-heading display-4">Here u got database *_*</h1> 
     </div> 
     <div> 
      <Limit handleChange = {this.handleChangeLimit} /> 
     </div> 
     <div> 
      <OriginRow handleChange = {this.handleChangeOrigin} /> 
     </div> 
     <div id="tableWrapper"> 
      <MainTable link={link} /> 
     </div> 
     </div> 
    ); 
    } 
} 

Und ich habe ein Problem mit ihm, denn wenn ich componentDidMount() verwenden, meine axios.get(my link to REST JSON) läuft nur einmal. Wenn ich axios in Table class render() verwende, trifft es meinen Server einige Male pro Sekunde. Kann ich die Montage nur durchführen, wenn sich meine Requisiten in der Tischklasse geändert haben?

+0

* "Kann ich die Montage nur durchführen, wenn sich meine Requisiten in der Table-Klasse geändert haben?" * - Meinst du die 'TableMain'-Komponente? Weil 'Table' eine Reaktiv-Bootstrap-Komponente ist. – Chris

+0

'MainTable-Klasse', genau. Entschuldigung, ich könnte genauer sein. –

Antwort

0

Sie sollten sich die shouldComponentUpdate() Life-Cycle-Methode, here ansehen.

shouldComponentUpdate()

shouldComponentUpdate(nextProps, nextState) 

Verwenden shouldComponentUpdate() wissen zu lassen, reagieren, wenn der Ausgang des Komponente nicht von der aktuellen Änderung des Zustands oder Requisiten betroffen ist. Das Standardverhalten besteht darin, bei jeder Statusänderung erneut zu rendern, und in den meisten Fällen sollten Sie sich auf das Standardverhalten verlassen.

shouldComponentUpdate() wird vor dem Rendern aufgerufen, wenn neue Requisiten oder Status empfangen werden. Standardeinstellung ist true. Diese Methode wird nicht beim ersten Rendern oder bei Verwendung von forceUpdate() aufgerufen.


Fügen Sie den folgenden Code-Schnipsel zu Ihrem MainTable Komponente. Dies verhindert ein erneutes Rendern, es sei denn, die props haben sich geändert.

shouldComponentUpdate(nextProps) { 
    return JSON.stringify(this.props) !== JSON.stringify(nextProps); 
} 

wird dies prüfen alle Requisiten. Wenn Sie gegen eine spezifische prop überprüfen möchten, können Sie tun:

shouldComponentUpdate(nextProps) { 
    return JSON.stringify(this.props.link) !== JSON.stringify(nextProps.link); 
} 

Wie in den Kommentaren darauf hingewiesen, gibt es immer eine kleine Chance, dass JSON.stringify(this.props) !== JSON.stringify(nextProps)false zurückkehren, selbst wenn sie gleich.

Wenn Sie also eine robustere Methode zum Vergleich des Objekts this.props mit dem Objekt newProps wünschen, sollten Sie einen Blick auf this post werfen.

+0

'JSON.Stringify' ist nicht in der Reihenfolge der Schlüssel stabil, so dass dies einen Fehler verursacht. Zumindest ein Fehler, der in diesem Fall normalerweise zu einem erneuten Rendern führt, wo es nicht gewünscht wurde. –

+0

Vielen Dank, aber noch eine Frage. Wie man meine 'MainTable' beim Start ausführt, habe ich eine ampty' Table' vor dem Filtern bekommen, und ich möchte die gesamte Datenbank dort wie vorher bekommen. –

+0

Objekte in JavaScript sind nicht geordnet und stringify sortiert sie auch nicht, Sie verlassen sich also nur auf undefiniertes Verhalten. Siehe https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify –

4

Wie bereits erwähnt, können Sie sollteComponentUpdate implementieren. Alternativ, wenn Sie nicht einen tiefen Vergleich benötigen, dh auf alle Sammlungen oder Objekte, nur PureComponent anstelle von Komponente:

https://github.com/facebook/react/blob/master/docs/docs/reference-react.md

React.PureComponent # React.PureComponent genau wie React.Component ist aber implementiert shouldComponentUpdate () mit einem flachen Prop - und Zustandsvergleich.

1

Dank für die Hilfe, die beste Lösung, die ich gefunden und wählen ist:

componentDidMount() { 
    axios.get(this.props.link) 
     .then(res => { 
     this.setState({results: res.data.results, count: res.data.count}); 
    }); 
    } 

    componentWillReceiveProps(nextProps) { 
    axios.get(nextProps.link) 
     .then(res => { 
     this.setState({results: res.data.results, count: res.data.count}); 
    }); 
    } 

Es ist genau das, was ich brauche, Sie hier zu lesen: https://facebook.github.io/react/docs/react-component.html#componentwillreceiveprops. Es wiederholt meine render() jedes Mal, wenn ich neue props bekomme und ich nicht axios in meinem render, die attraktiver ist.

Verwandte Themen