react_Kons

03 what's your name!

var test = (<div>
<p>Hey there. Enter your name.</p>
 <input type="text" name="name" onChange={this.onNameChange} />
    </div>);
    if(this.state.name.length === 0)
      return test;
    else{
      return (
        <div>
          <p>Hello {this.state.name}</p>
          <input type="text" name="name" onChange={this.onNameChange} />
        </div>
      );
    }

05 GroceryList 01

Properties are a way to pass parameters to your React components.Properties are to React components what attributes are to HTML elements.

state 更像是把值赋给一个组件,通常初始一个state,然后父组件像这样子<component test={this.state.xx} key={index}/> 然后子组件就可以return(<p key={this.props.key}>{this.props.test.xx}</p> )渲染了,就基本是这个套路。

class GroceryList extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      groceries: [ { name: "Apples" } ]
    };
  }
  render() {
    let groceriesComponents = [];
    // Properties are a way to pass parameters to your React components.
    // We mentioned this in the third exercise. Properties are to React
    // components what attributes are to HTML elements.
    //
    // Below you can see how to pass properties to child components.
    // We have defined a `grocery` property for each `GroceryListItem`.
    for(var index = 0; index < this.state.groceries.length; index++) {
      groceriesComponents.push(
          <GroceryListItem
            grocery={this.state.groceries[index]}
            key={index}
          />
      );
    }
    // Hint: Don't forget about putting items into `ul`
    return (
      <div>
        // Put your code here
        <ul>
         {groceriesComponents}
        </ul>
      </div>
    );
  }
}
// Render grocery name from component's properties.
// If you have a problem, check `this.props` in the console.
class GroceryListItem extends React.Component {
  constructor(props) {
    super(props);
  }
  render() {
          // Put your code here.
         return(
            <li key={this.props.key}>{this.props.grocery.name}</li>
          )
  }
}

05 GroceryList 02

通过这个练习基本熟悉了state的用法,首先state一般用于设置初始值,然后通过setState({key:val})设置,注意,这里只要一使用setState就会触发重新渲染render()方法,然后在后续组件中想办法使之改变。
(遇到问题想办法解决,一步一步来,注意看浏览器报错.使用console.log来打印每一步的状态)

var React = require("react");
// We continue our journey with reactive grocery list. We implemented the previous
// task ourselves. You can see our example implementation.
//
// Task: You have to implement adding items to the list. Create the implementation
//       of the `addGroceryItem` method. This method should modify the `GroceryList`
//       component's state and by that re-render this component.
//
//       You need to render an input and button in `GroceryList` (after the
//       groceries list). Users will use them as an input for new groceries.
//
//       We prepared two components for you. Please render the button and
//       input under your list and define the `onClick` handler for the button.
//
//       Hint: See `render` method body. Look for `newProductInput` and
//             `newProductAddButton` variables
//
//       Do you remember how we used `onChange` event in the third exercise?

 // 问题1 到底是拼接之后还是替换 
 //  问题2 先实现改变就回显的功能,现在是只要光标以改变就会重新setState

class GroceryList extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      groceries: [
        { name: "Apples" }
      ],
      newGroceryName: ""
    };
//  这里的bind 是几个意思??
    this.addGroceryItem = this.addGroceryItem.bind(this);
    this.inputChanged = this.inputChanged.bind(this);
  }
  // Warning: You shouldn't change this method
  inputChanged(event) {
    this.setState({newGroceryName: event.target.value});
  }
  // Fill the definition of the following method to allow adding new items to the list
  // Hint #1: You should use the `concat` function to modify groceries list.
  // Hint #2: Remember about the case where input is empty.
  // Hint #3: Name of the new grocery item will be stored in `this.state.newGroceryName`.
  addGroceryItem() {
    // Put your code here
     //console.log(this.state);
     if(this.state.newGroceryName){
    var groceriesVal= this.state.groceries.concat({'name':this.state.newGroceryName});
  this.setState({groceries:groceriesVal})
}
  }
  render() {

    let groceriesComponents = [],
        newProductInput,
        newProductAddButton;

    for(var index = 0; index < this.state.groceries.length; index++) {
      groceriesComponents.push(
          <GroceryListItem
            grocery={this.state.groceries[index]}
          />
      );
    }
    // Here are components for task #2.
    newProductInput = <input className='new-item' type="text" onChange={this.inputChanged}/>;
    // Something is missing here... Will anything happen if you click this button now?
    newProductAddButton = <button className='add-product' onClick={this.addGroceryItem}>Add new Product</button>;
    return (
      <div>
        <ul>
          {groceriesComponents}
          {newProductInput}
          {newProductAddButton}
        </ul>
      </div>
    );
  }
}
class GroceryListItem extends React.Component {
  constructor(props) {
    super(props);
  }
  render() {
    return (<li>{this.props.grocery.name}</li>);
  }
}
export default GroceryList;


todolist

任务相当于做一个类似于todolist的东西,点击改变样式.
思路是给每个li绑定点击事件,然后反转这个li下的complete属性,最后自然是setState。难点是可能没有想到给每个item 加index 导致无法绑定。多思考,多看提示会少踩坑
(这段代码没有写出来,主要原因是因为不理解bind方法,然后没有理解传参那一步。)

class GroceryList extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      groceries: [
        {
          name: "Apples",
          completed: false
        }
      ],
      newGroceryName: ""
    };

    this.addGroceryItem = this.addGroceryItem.bind(this);
    this.clearList = this.clearList.bind(this);
    this.inputChanged = this.inputChanged.bind(this);
  }

  inputChanged(event) {
    this.setState({ newGroceryName: event.target.value });
  }

  addGroceryItem() {
    if(this.state.newGroceryName) {
      let newGroceryItem = { name: this.state.newGroceryName };
      this.setState({
        groceries: this.state.groceries.concat([newGroceryItem])
      });
    }
  }

  clearList(event) {
    this.setState({groceries: []});
  }

  // Fill the definition of the following method to allow completing each item
  // Hint 1: Pay attention to the element's index on the list.
  toggleGroceryCompleteness(groceryIndex) {
    var groceryCompleted = this.state.groceries[groceryIndex].completed;

    var grocery = this.state.groceries[groceryIndex];
    grocery.completed = !grocery.completed;

    this.setState({
      groceries: this.state.groceries
    })
  }

  render() {
    let groceriesComponents = [],
        newProductInput,
        newProductAddButton,
        clearListButton;
    for(var index = 0; index < this.state.groceries.length; index++) {
      groceriesComponents.push(
          <GroceryListItem
            grocery={this.state.groceries[index]}
            onComplete={this.toggleGroceryCompleteness.bind(this, index)}
          />
      );
    }
//不理解bind(this)有什么用  onComplete={this.toggleGroceryCompleteness.bind(this, index)} 黑人问号???!!!
// 上面那个方法调用好像是指将这个方法绑定到这个元素上,传进变量index!!!  注意理解
//  这道题到底是要干嘛啊?给每个属性加了一个complete属性。每个 li 上有个onComplete事件,点击之后如何切换?
//  大概意思好像是点击li 标签,实现该元素下complete的切换
    newProductInput = <input className='new-item' type="text" onChange={this.inputChanged}/>;
    newProductAddButton = <button className='add-product' onClick={this.addGroceryItem}>Add new Product</button>;
    clearListButton = <button className='clear-list' onClick={this.clearList}>Clear the List</button>;

    return (
      <div>
        <ul>
          {groceriesComponents}
        </ul>
        {newProductInput}
        {newProductAddButton}
        {clearListButton}
      </div>
    );
  }
}

class GroceryListItem extends React.Component {
  constructor(props) {
    super(props);
  }

  render() {
    //这个complete主要是切换属性  onClick方法是怎么回事?父元素中有一个onComplete方法
    let completed = this.props.grocery.completed ? "completed" : '';
    //console.log(completed);
    return (
      <li className={completed} onClick={this.props.onComplete}>
        {this.props.grocery.name}
      </li>
    );
  }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容