0.0

使用create-react-app

新知识

  • _import_ React _from_ 'react';之后首字母大写代表组件
  • _import_ React _from_ 'react';之后首字母大写代表组件
  • key:组件中li不给一个不同的key会有警告,但这个为什么我还没去了解

    1. <ul>
    2. {
    3. this.state.list.map((item,index)=>{
    4. return <li key={index} onClick={this.handleItemClick.bind(this,index)}>{item}</li>
    5. }) //可以通过传入map函数的第二个参数--下标来当key以达到目的
    6. }
    7. </ul>
  • setstate来设置state

  • constructor(props){_//组件被调用时会自动该构造函数_
  • _super_(props);_//初始化,先不管为什么_
  • this.state装数据内容
  • 调用各种绑定事件的方法时,要再.bind(this),因为想要的this是组件,而不绑定调用组件中的方法时默认的是事件绑定的东西—button或者什么东西
  • index.js是网页的入口

    思想

  • 尽量不要操作dom,而是操作数据,react会根据数据变化重新渲染页面

  • 页面由各个组件构成,一切都组件化。
  • 修改state里的东西尽量不要直接修改 而是通过 拷贝一个副本 操作这个副本后赋值回去 这样以后借助一些工具调试会比较简单

    功能

    新增功能

    1. class TodoList extends React.Component{
    2. constructor(props){//组件被调用时会自动该构造函数
    3. super(props);//初始化
    4. this.state={//数据内容
    5. list:[],
    6. }
    7. }
    8. handleBtnClick(){//被调用时 this默认指向Btn按钮 所以要在调用时手动绑定一个
    9. //必须要调用react提供的的方法setstate来修改state
    10. if(this.state.inputValue){
    11. this.setState({
    12. list:[...this.state.list,this.state.inputValue],
    13. inputValue:''
    14. })
    15. }
    16. }
    17. handInputChange(e){
    18. this.setState({
    19. inputValue:e.target.value
    20. })
    21. }
    22. render() {
    23. return (
    24. <div>
    25. <div>
    26. this.state.inputValuevalue绑在一块来实现add之后刷新输入栏
    27. <input value={this.state.inputValue} onChange={this.handInputChange.bind(this)/>
    28. {/* 手动绑定this 使函数调用时this始终指向函数前面那个this而不是btn */}
    29. <button onClick={this.handleBtnClick.bind(this)}>add</button>
    30. </div>
    31. <div>
    32. <ul>
    33. {
    34. this.state.list.map((item,index)=>{
    35. return <li key={index} >{item}</li>
    36. })
    37. }
    38. </ul>
    39. </div>
    40. </div>
    41. );
    42. }
    43. }

    删除功能

    ```javascript class TodoList extends React.Component{ constructor(props){//组件被调用时会自动该构造函数 super(props);//初始化 this.state={//数据内容

    1. list:[],
    2. inputValue:''

    } } handleBtnClick(){//被调用时 this默认指向Btn按钮 所以要在调用时手动绑定一个 //必须要调用react提供的的方法setstate来修改state if(this.state.inputValue){

    1. this.setState({
    2. list:[...this.state.list,this.state.inputValue],
    3. inputValue:''
    4. })

    } } handInputChange(e){ this.setState({

    1. inputValue:e.target.value

    }) } handleItemClick(index){ const list = […this.state.list]; list.splice(index,1); this.setState({

    1. list

    }) } render() { return (

    1. <div>
    2. <div>
    3. <input value={this.state.inputValue} onChange={this.handInputChange.bind(this)}/>
    4. {/* 手动绑定this 使函数调用时this始终指向函数前面那个this而不是btn */}
    5. <button onClick={this.handleBtnClick.bind(this)}>add</button>
    6. </div>
    7. <div>
    8. <ul>
    9. {
    10. this.state.list.map((item,index)=>{
    11. return <li key={index} onClick={this.handleItemClick.bind(this,index)}>{item}</li>
    12. })
    13. }
    14. </ul>
    15. </div>
    16. </div>

    ); } }

  1. <a name="pzU1G"></a>
  2. ## 组件的拆分
  3. <a name="dLGzC"></a>
  4. ### 把列表项单独地拆分出去
  5. <a name="ZpaNl"></a>
  6. #### 父子组件的概念
  7. 在组件中调用另一个组件,被调用的组件就是子组件
  8. <a name="C25ae"></a>
  9. ##### 父子件给子组件传递
  10. 通过属性的方式向子组件传递参数<br />子组件通过`props`的方式来接受父组件传递的参数
  11. <a name="neK4Z"></a>
  12. ##### 子组件向父子件传递
  13. 子组件如果想和父组件通信,子组件要调用父组件传递过来的方法<br />`ToDoItem.js`:
  14. ```javascript
  15. import React from 'react';
  16. class TodoItem extends React.Component{
  17. //子组件如果想和父组件通信,子组件要调用父组件传递过来的方法
  18. handleDelete(){
  19. this.props.delete(this.props.index);//把index传递给父组件
  20. }
  21. render(){
  22. return (
  23. <div onClick={this.handleDelete.bind(this)}>{this.props.content}</div>
  24. )
  25. }
  26. }
  27. export default TodoItem;

ToDoList.js修改处:

  1. // handleItemClick(index){
  2. // const list = [...this.state.list];
  3. // list.splice(index,1);
  4. // this.setState({
  5. // list
  6. // })
  7. // }
  8. handleDelete(index){
  9. // console.log(index);
  10. const list = [...this.state.list];
  11. list.splice(index,1);
  12. this.setState({
  13. list
  14. })
  15. }
  16. this.state.list.map((item,index)=>{
  17. // return <li key={index} onClick={this.handleItemClick.bind(this,index)}>{item}</li>
  18. return <ToDoItem delete={this.handleDelete.bind(this)} key={index} content={item} index={index}/>
  19. })

代码优化

bind绑定

在代码中可以看到绑定事件的代码都需要.bind(this),可以在construtor中添加绑定

  1. constructor(props){//组件被调用时会自动该构造函数
  2. ......
  3. //代码简洁,性能也有提高,具体原理我还不清楚
  4. this.handleInputChange=this.handleInputChange.bind(this)
  5. this.handleBtnClick=this.handleBtnClick.bind(this)
  6. this.handleDelete=this.handleDelete.bind(this)
  7. }

return中代码

  1. return (
  2. <ToDoItem
  3. delete={this.handleDelete}
  4. key={index}
  5. content={item}
  6. index={index}
  7. />
  8. );

render方法返回的太长了

  1. .....
  2. getToDoItems(){
  3. return(
  4. this.state.list.map((item,index)=>{
  5. // return <li key={index} onClick={this.handleItemClick.bind(this,index)}>{item}</li>
  6. return (
  7. <ToDoItem
  8. delete={this.handleDelete}
  9. key={index}
  10. content={item}
  11. index={index}
  12. />
  13. );
  14. })
  15. )
  16. }
  17. render() {
  18. return (
  19. <div>
  20. <div>
  21. <input value={this.state.inputValue} onChange={this.handleInputChange}/>
  22. {/* 手动绑定this 使函数调用时this始终指向函数前面那个this而不是btn */}
  23. <button onClick={this.handleBtnClick}>add</button>
  24. </div>
  25. <div>
  26. <ul>{this.getToDoItems()}</ul>//*******
  27. </div>
  28. </div>

es6的解构赋值

const {content}=_this_.props;

  1. return (
  2. <div onClick={this.handleDelete}>{content}</div>
  3. //这的content本来是this.props.content
  4. )

const {AA,BB,CC,…}=this.props 这里的是es6的一个方法来的 等价于 this.props={AA:’AA值’,BB:’BB值’,CC:’CC值’,

react的引用

import React,{Component,Fragment} from 'react';
这样继承时就可以class TodoList extends Component而不用React.Component,下一步中使用Fragment也是一个道理

CSS样式修饰

style方式

例子
image.png
` <button _style_={{background:'red'}} _onClick_={_this_.handleBtnClick}>add</button><br />需要这么写style中最外层{}说明是一个js语句,里面的{}说明是js的对象,注意赋值的red是‘red’`

class方式

<button _class_='red-btn'如果用class则会有警告
image.png
这是因为 classreact中代表的是组件,需要用className代替
创建一个style.css
image.png
在入口调用他
image.png

外层div标签的去除

reactrender返回的jsx必须只有一个,所以必须要有一个最外层包裹住所有,但有时又确实不想要最外层的div就可以选择使用<React.Fragment>代替,代码优化后直接<Fragment>就可以了