0.0
新知识
- 在
_import_ React _from_ 'react';
之后首字母大写代表组件 - 在
_import_ React _from_ 'react';
之后首字母大写代表组件 key:组件中
li
不给一个不同的key
会有警告,但这个为什么我还没去了解<ul>
{
this.state.list.map((item,index)=>{
return <li key={index} onClick={this.handleItemClick.bind(this,index)}>{item}</li>
}) //可以通过传入map函数的第二个参数--下标来当key以达到目的
}
</ul>
setstate
来设置state
constructor(props){_//组件被调用时会自动该构造函数_
_super_(props);_//初始化,先不管为什么_
this.state
装数据内容- 调用各种绑定事件的方法时,要再
.bind(this)
,因为想要的this
是组件,而不绑定调用组件中的方法时默认的是事件绑定的东西—button或者什么东西 -
思想
尽量不要操作dom,而是操作数据,react会根据数据变化重新渲染页面
- 页面由各个组件构成,一切都组件化。
修改state里的东西尽量不要直接修改 而是通过 拷贝一个副本 操作这个副本后赋值回去 这样以后借助一些工具调试会比较简单
功能
新增功能
class TodoList extends React.Component{
constructor(props){//组件被调用时会自动该构造函数
super(props);//初始化
this.state={//数据内容
list:[],
}
}
handleBtnClick(){//被调用时 this默认指向Btn按钮 所以要在调用时手动绑定一个
//必须要调用react提供的的方法setstate来修改state
if(this.state.inputValue){
this.setState({
list:[...this.state.list,this.state.inputValue],
inputValue:''
})
}
}
handInputChange(e){
this.setState({
inputValue:e.target.value
})
}
render() {
return (
<div>
<div>
用this.state.inputValue与value绑在一块来实现add之后刷新输入栏
<input value={this.state.inputValue} onChange={this.handInputChange.bind(this)/>
{/* 手动绑定this 使函数调用时this始终指向函数前面那个this而不是btn */}
<button onClick={this.handleBtnClick.bind(this)}>add</button>
</div>
<div>
<ul>
{
this.state.list.map((item,index)=>{
return <li key={index} >{item}</li>
})
}
</ul>
</div>
</div>
);
}
}
删除功能
```javascript class TodoList extends React.Component{ constructor(props){//组件被调用时会自动该构造函数 super(props);//初始化 this.state={//数据内容
list:[],
inputValue:''
} } handleBtnClick(){//被调用时 this默认指向Btn按钮 所以要在调用时手动绑定一个 //必须要调用react提供的的方法setstate来修改state if(this.state.inputValue){
this.setState({
list:[...this.state.list,this.state.inputValue],
inputValue:''
})
} } handInputChange(e){ this.setState({
inputValue:e.target.value
}) } handleItemClick(index){ const list = […this.state.list]; list.splice(index,1); this.setState({
list
}) } render() { return (
<div>
<div>
<input value={this.state.inputValue} onChange={this.handInputChange.bind(this)}/>
{/* 手动绑定this 使函数调用时this始终指向函数前面那个this而不是btn */}
<button onClick={this.handleBtnClick.bind(this)}>add</button>
</div>
<div>
<ul>
{
this.state.list.map((item,index)=>{
return <li key={index} onClick={this.handleItemClick.bind(this,index)}>{item}</li>
})
}
</ul>
</div>
</div>
); } }
<a name="pzU1G"></a>
## 组件的拆分
<a name="dLGzC"></a>
### 把列表项单独地拆分出去
<a name="ZpaNl"></a>
#### 父子组件的概念
在组件中调用另一个组件,被调用的组件就是子组件
<a name="C25ae"></a>
##### 父子件给子组件传递
通过属性的方式向子组件传递参数<br />子组件通过`props`的方式来接受父组件传递的参数
<a name="neK4Z"></a>
##### 子组件向父子件传递
子组件如果想和父组件通信,子组件要调用父组件传递过来的方法<br />`ToDoItem.js`:
```javascript
import React from 'react';
class TodoItem extends React.Component{
//子组件如果想和父组件通信,子组件要调用父组件传递过来的方法
handleDelete(){
this.props.delete(this.props.index);//把index传递给父组件
}
render(){
return (
<div onClick={this.handleDelete.bind(this)}>{this.props.content}</div>
)
}
}
export default TodoItem;
ToDoList.js
修改处:
// handleItemClick(index){
// const list = [...this.state.list];
// list.splice(index,1);
// this.setState({
// list
// })
// }
handleDelete(index){
// console.log(index);
const list = [...this.state.list];
list.splice(index,1);
this.setState({
list
})
}
this.state.list.map((item,index)=>{
// return <li key={index} onClick={this.handleItemClick.bind(this,index)}>{item}</li>
return <ToDoItem delete={this.handleDelete.bind(this)} key={index} content={item} index={index}/>
})
代码优化
bind绑定
在代码中可以看到绑定事件的代码都需要.bind(this)
,可以在construtor
中添加绑定
constructor(props){//组件被调用时会自动该构造函数
......
//代码简洁,性能也有提高,具体原理我还不清楚
this.handleInputChange=this.handleInputChange.bind(this)
this.handleBtnClick=this.handleBtnClick.bind(this)
this.handleDelete=this.handleDelete.bind(this)
}
return中代码
return (
<ToDoItem
delete={this.handleDelete}
key={index}
content={item}
index={index}
/>
);
render方法返回的太长了
.....
getToDoItems(){
return(
this.state.list.map((item,index)=>{
// return <li key={index} onClick={this.handleItemClick.bind(this,index)}>{item}</li>
return (
<ToDoItem
delete={this.handleDelete}
key={index}
content={item}
index={index}
/>
);
})
)
}
render() {
return (
<div>
<div>
<input value={this.state.inputValue} onChange={this.handleInputChange}/>
{/* 手动绑定this 使函数调用时this始终指向函数前面那个this而不是btn */}
<button onClick={this.handleBtnClick}>add</button>
</div>
<div>
<ul>{this.getToDoItems()}</ul>//*******
</div>
</div>
es6的解构赋值
const {content}=_this_.props;
return (
<div onClick={this.handleDelete}>{content}</div>
//这的content本来是this.props.content
)
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方式
例子` <button _style_={{background:'red'}} _onClick_={_this_.handleBtnClick}>add</button><br />需要这么写
style中最外层
{}说明是一个
js语句,里面的
{}说明是
js的对象,注意赋值的red是
‘red’`
class方式
<button _class_='red-btn'
如果用class
则会有警告
这是因为 class
在react
中代表的是组件,需要用className
代替
创建一个style.css
在入口调用他
外层div标签的去除
react
中render
返回的jsx
必须只有一个,所以必须要有一个最外层包裹住所有,但有时又确实不想要最外层的div
就可以选择使用<React.Fragment>
代替,代码优化后直接<Fragment>
就可以了