【问题标题】:React - setting stateReact - 设置状态
【发布时间】:2017-05-30 05:52:44
【问题描述】:

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

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]: 竞赛”也让我感到困惑。如果有人能提供一些澄清,将不胜感激!

【问题讨论】:

    标签: javascript json node.js reactjs axios


    【解决方案1】:

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

    [contest.id]: contest 正在计算密钥。见Computed property keys

    例如,假设 contest.id34,并且 state.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
    }
    

    【讨论】:

    • 啊,我明白了 - 谢谢。我的部分困惑是试图理解为什么他会将整个比赛分配给比赛.id,但 id 与比赛在比赛对象中的位置相同(按顺序),并且 [contest.id] = 比赛行只是将该竞赛对象更新为新的竞赛对象,因为在 axios 调用中检索竞赛时,我忘记注意到在 api 路由器中添加了一个竞赛描述,这是竞赛组件的一部分的必需属性.
    猜你喜欢
    • 1970-01-01
    • 2018-06-13
    • 2020-11-02
    • 1970-01-01
    • 2015-11-19
    • 2019-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多