2017-01-15 124 views
0

我正在关注Samer Buna的Lynda课程“完全堆栈JavaScript开发:MongoDB,Node和React”,并且想知道“命名比赛”应用程序的App组件中的一段代码。我的问题是关于前端React App组件,特别是设置状态。我无法搞清楚码块是:React - 设置状态

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

在App组分fetchContest()函数内部 - 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是内部的唯一的文件'API' 目录中,并且它包括一个Axios公司呼叫以检索对应于每个竞赛JSON对象:

api.js:

import axios from 'axios'; 

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

参考,争奇斗艳的JSON内容是这样的:

{ 
    "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" 
    } 
    ] 
} 

我以前见过的传播经营者,但我不确定它是如何在这种情况下究竟使用。此外,'[contest.id]:比赛'也令我困惑。如果有人可以提供一些澄清,将非常感谢!

回答

2

因此,spread操作符会将一个对象的所有键和值复制到另一个对象中。在Redux reducer的情况下,这通常用于克隆状态并使存储不可变。

[contest.id]: contest正在计算一个关键。见Computed property keys

例如,给定contest.id34state.constests包含大赛32和33,你会与对象恰似结束:

{ 
    '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

我明白了 - 谢谢。我的一部分困惑是试图理解他为什么要分配参加比赛。在整个比赛中,但身份证与比赛对象中的比赛位置相同(通过顺序),[比赛比赛] =比赛只是将比赛对象更新为新的比赛对象,因为当在axios调用中检索比赛时,我忘记了注意在api路由器中添加了比赛。描述,这是作为比赛组件的一部分的必需属性。 –