1.1 初探
index.js:
import React from 'react';
import ReactDOM from 'react-dom';
import TodoList from './TodoList';
ReactDOM.render(<TodoList />, document.getElementById('root'));
todoList.js
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
class TodoList extends Component {
render() {
return (
<div>TodoList</div>
<ul>
<li>学习</li>
<li>写作</li>
</ul>
)
}
}
export default TodoList; //把自身导出,外部才可以引用。
会报下面的错
./src/TodoList.jsSyntax error: Adjacent JSX elements must be wrapped in an enclosing tag (8:6)
这是因为在jsx的语法中,一个组件render函数返回的内容外层必须要有一个包裹元素。现在有两个,一个<ul>
,一个 <div>
,在外层加个<div>
即可。
如果不想套用一个div怎么办?
在react16的语法中,react提供了一个叫Fragiment
的占位符。
return (
<Fragment>
<div>TodoList</div>
<ul>
<li>学习</li>
<li>写作</li>
</ul>
</Fragment>
)
2.2 React中的响应式设计思想和事件绑定
react
英文就是响应的意思,react
跟英文名一样的含义:数据响应,页面发生变化。
react更改state的状态的话不能通过以下来进行修改
this.state.inputValue = e.target.value //e.target会获取dom节点,再.value就会获取value值
而是用react提供的方法setState
import React, { Component, Fragment } from 'react';
import ReactDOM from 'react-dom';
class TodoList extends Component {
constructor(props) {
super(props)
this.state = {
inputValue: '',
list: []
}
}
handleInputChange (e) {
this.setState({
inputValue: e.target.value
})
}
render() {
return (
<Fragment>
<div>
<input value={this.state.inputValue} onChange={this.handleInputChange.bind(this)} />
<button>提交</button>
</div>
<ul>
<li>学习</li>
<li>写作</li>
</ul>
</Fragment>
)
}
}
export default TodoList; //把自身导出,外部才可以引用。
介绍:
页面刚开始初始化的时候,会有两个初始值inputValue
和list
值,render
会渲染值为this.state.inputValue
会初始化值,然后输入内容onChange
会执行,e.target.value
会获取值,然后改变inputValue
的值,inputValue
的值发生改变了,页面input
标签里的值发生了改变,那么页面也会发生改变。
注意:
js表达式用{}
时间绑定用bind(this)
对函数的作用域进行变更,改变this
的指向
setState
来对数据项就行改变
2.3 实现todoList新增删除功能
增加功能
list: ['study1', 'study2']
...
<ul>
{
this.state.list.map((item, index) => {
return <li>{item}</li>
})
}
</ul>
这里就会有生成两个li
,也就是list中的值。所以我们实现增加功能,不用关注dom,只需要关注数据就行了。要做的就是把inputValue
的值放在 list
中即可。这样数组中有内容,页面就会接着变了。
handleBtnClick() {
this.setState({
list: [...this.state.list, this.state.inputValue]
})
}
...
是es6的展开运算符,...this.state.list
指的是初始化是时候list所定义的值。把以前的数组展开生成全新的数组,所以外面套个[]
会发现页面报Warning: Each child in an array or iterator should have a unique "key" prop.
<ul>
{
this.state.list.map((item, index) => {
return <li key={index}>{item}</li>
})
}
</ul>
map循环需要加上key,key必须保证唯一,要不会报警告,这里用index
删除功能
点击item
的时候获取下标值。把index
放在bind
函数中,传递给delete方法,用splice
方法删除即可。
import React, { Component, Fragment } from 'react';
import ReactDOM from 'react-dom';
class TodoList extends Component {
constructor(props) {
super(props)
this.state = {
inputValue: '',
list: []
}
}
handleInputChange (e) {
this.setState({
inputValue: e.target.value
})
}
handleBtnClick() {
this.setState({
list: [...this.state.list, this.state.inputValue],
inputValue: ''
})
}
// 删除
handleItemDelete (index) {
// immutable
// state 不允许我们做任何改变
const list = [...this.state.list]
list.splice(index, 1)
this.setState({
list: list
})
}
render() {
return (
<Fragment>
<div>
<input value={this.state.inputValue} onChange={this.handleInputChange.bind(this)} />
<button onClick={this.handleBtnClick.bind(this)}>提交</button>
</div>
<ul>
{
this.state.list.map((item, index) => {
return (<li
key={index}
onClick={this.handleItemDelete.bind(this, index)}>
{item}</li>
)
})
}
</ul>
</Fragment>
)
}
}
export default TodoList; //把自身导出,外部才可以引用。
以上。
网友评论