2017-01-15 7 views
0

Ich folge Samer Buna's Lynda-Kurs über "Full-Stack-JavaScript-Entwicklung: MongoDB, Knoten und Reagieren" und frage mich nach einem Code in der App-Komponente der "Naming Contests" -Anwendung. Meine Fragen beziehen sich auf die Front-End-React-App-Komponente und insbesondere auf die Einstellung des Status. Der Codeblock ich Probleme, bin herauszufinden, ist:React - Setting Status

contests: { 
      ...this.state.contests, 
      [contest.id]: contest 
     } 

innerhalb der fetchContest() Funktion in der App-Komponente - App.js:

import React from 'react'; 
import Header from './Header'; 
import ContestList from './ContestList'; 
import Contest from './Contest'; 
import * as api from '../api'; 

const pushState =(obj, url) => 
    window.history.pushState(obj, '', url); 

class App extends React.Component { 
    static propTypes = { 
    initialData: React.PropTypes.object.isRequired 
    }; 
    state = this.props.initialData; 
    componentDidMount() {} 
    componentWillUnmount() {} 
    fetchContest = (contestId) => { 
    pushState(
     { currentContestId: contestId }, 
     `/contest/${contestId}` 
    ); 
    api.fetchContest(contestId).then(contest => { 
     this.setState({ 
     currentContestId: contest.id, 
     contests: { 
      ...this.state.contests, 
      [contest.id]: contest 
     } 
     }); 
    }); 
    // lookup the contest 
    // convert contests from array to object, for constant time lookup 
    // this.state.contests[contestId] 
    } 
    pageHeader() { 
    if (this.state.currentContestId) { 
     return this.currentContest().contestName; 
    } 

    return 'Naming Contests'; 
    } 
    currentContest() { 
    return this.state.contests[this.state.currentContestId]; 
    } 
    currentContent() { 
    if (this.state.currentContestId) { 
     return <Contest {...this.currentContest()} />; 
    } 

    return <ContestList 
     onContestClick={this.fetchContest} 
     contests={this.state.contests} />; 
    } 
    render() { 
    return (
    <div className="App"> 
     <Header message={this.pageHeader()} /> 
     {this.currentContent()} 
    </div> 
    ); 
    } 
} 

export default App; 

api.js ist die einzige Datei innerhalb der 'api' Verzeichnis, und es enthält einen axios Anruf ein json Objekt entsprechend jedem Wettbewerb abzurufen:

api.js:

import axios from 'axios'; 

export const fetchContest = (contestId) => { 
    return axios.get(`/api/contests/${contestId}`) 
       .then(resp => resp.data); 
}; 

als Referenz, schauen die json Inhalt der Wettbewerbe wie folgt aus:

{ 
    "contests": [ 
    { 
     "id": 1, 
     "categoryName": "Business/Company", 
     "contestName": "Cognitive Building Bricks" 
    }, 
    { 
     "id": 2, 
     "categoryName": "Magazine/Newsletter", 
     "contestName": "Educating people about sustainable food production" 
    }, 
    { 
     "id": 3, 
     "categoryName": "Software Component", 
     "contestName": "Big Data Analytics for Cash Circulation" 
    }, 
    { 
     "id": 4, 
     "categoryName": "Website", 
     "contestName": "Free programming books" 
    } 
    ] 
} 

Ich habe vor der Ausbreitung Operator gesehen, aber ich bin nicht sicher, wie es in diesem Zusammenhang genau verwendet wird. Auch der '[contest.id]: contest' verwirrte mich. Es würde sehr geschätzt werden, wenn jemand etwas Klarheit geben könnte!

Antwort

2

Der Spread-Operator wird also alle Schlüssel und Werte eines Objekts in ein anderes kopieren. Im Fall eines Redux-Reduzierers wird dies oft verwendet, um den Zustand zu klonen und den Speicher unveränderlich zu halten.

[contest.id]: contest berechnet einen Schlüssel. Siehe Computed property keys.

Zum Beispiel gegeben contest.id ist 34 und state.constests enthält Wettbewerb 32 und 33, die Sie ein Objekt am Ende dann aussehen wie:

{ 
    '32': {}, // This is the same value as it was in the initial store 
    '33': {}, // ... same here 
    '34': contest // That's the new contest you want to inject in the store 
} 
+0

Ah ich sehe - danke. Teil meiner Verwirrung war zu versuchen, zu verstehen, warum er zum contest.id den gesamten Wettbewerb zuweisen würde, aber die ID ist die gleiche wie die Position des Wettbewerbs im Wettbewerb Gegenstand (durch Sequenzialität), und der [contest.id] = Wettbewerb line aktualisiert gerade das Contest-Objekt auf das neue Contest-Objekt, da ich beim Abrufen des Contests im Axios-Call vergessen habe, dass im api-Router eine contest.description hinzugefügt wird, die eine erforderliche Eigenschaft als Teil der Contest-Komponente ist . –