使用环境:
- node -vv10.19.0
- npm -v6.13.4
- VSCode
1、在src\components\下面创建文件夹Like,创建src\components\Like\index.js
import React, { Component } from 'react'
export default class Like extends Component {
constructor(){
super()
this.state = {
isLike: false
}
}
//使用这种方式 修改数据在react里面是不允许的,能修改数据,但界面不能重新渲染
//this.state.isLike:!this.state.isLike
//要修改数据,就是用setState()方法,setState可以有2个参数
//setState是异步的
//第一个参数又有2中情况,第一种情况是一个对象
handleLikeClike = () =>{
// this.setState({
// isLike: !this.state.isLike
// })
//第二种情况是一个方法
this.setState((prevState,props) => {
console.log(prevState)
console.log("setState内部:",this.state.isLike)
return {
isLike: !prevState.isLike
}
},()=>{
//由于setState是异步,的想要获取最新的setState值,需要在回调中获取
console.log("setState回调:",this.state.isLike)
})
console.log("setState外部:",this.state.isLike)
}
render() {
return (
<div>
<span onClick = {this.handleLikeClike}>
{this.state.isLike == true ? "取消 ❤️":"喜欢 🖤"}
</span>
</div>
)
}
}
2、把添添加到:src\components\index.js
export { default as Like } from './Like'
3、src\App.js
import {
Like,
} from './components'
render() {
return (
<>
<Like />
</>
)
}
1、事件
(1)、src\components\TodoInput\index.js
import React, { Component } from 'react'
export default class TodoInput extends Component {
//构造函数
constructor(){
super()
this.state = {
inputValue: ''
}
}
handelInputChange = (e) => {
// console.log(e.currentTarget.value)
this.setState({
inputValue: e.currentTarget.value
})
}
handelButtonClick= () => {
//这里使用父组件的传递的方法
this.props.addTodo(this.state.inputValue)
}
render() {
return (
<div>
<input
type="text"
value={this.state.inputValue}
onChange={this.handelInputChange}
/><button onClick={this.handelButtonClick}>{this.props.btnText}:{this.props.inTudo}</button>
</div>
)
}
}
(2)、src\App.js
import React, { Component, Fragment } from 'react'
import {
TodoHeader,
TodoInput,
TodoList,
Like,
} from './components'
export default class App extends Component {
constructor(){
super()
this.state = {
desc : '受控组件',
inTudo : '添加',
article: '<div>使用dangerouslySetInnerHTML<i>如果包含html标签</i></div>',
todos : [{
id: 1,
title: '吃饭',
isCompleted: true
},{
id: 2,
title: '睡觉',
isCompleted: false
}]
}
}
//这里通过标签属性 <TodoInput addTodo={this.addTodo} 传递方法
//在子组件中可以通过this.props.addTodo 取出方法
addTodo = (todoTitle) => {
console.log(todoTitle)
//这样写出错。,因为push() 返回的是一个数组的长度
// this.setState = {
// todos:this.props.todos.push({
// id: Math.random(),
// title: todoTitle,
// isCompleted: false
// })
// }
//这样写不会出错,是对的
// this.setState = {
// todos:this.props.todos.concat({
// id: Math.random(),
// title: todoTitle,
// isCompleted: false
// })
// }
//const newTodos = this.state.todos.slice()
const newTodes = [...this.state.todos]
newTodes.push({
id: Math.random(),
title: todoTitle,
isCompleted: false
})
this.setState({
todos: newTodes
})
}
render() {
return (
// <div>
// <TodoHeader />
// <TodoInput />
// <TodoList />
// </div>
// 特殊功能。不需要外边得div有下面2中方式
//第一种:空标签
// <>
// <TodoHeader />
// <TodoInput />
// <TodoList />
// </>
//第二种:使用React中的方法Fragment
<Fragment>
<TodoHeader
titel="待办事项"
desc={this.state.desc}
/>
<TodoInput
addTodo={this.addTodo}
btnText="ADD"
inTudo={this.state.inTudo}
/>
<TodoList
todos={this.state.todos}
/>
{/* 渲染值中含有html标签需要使用一下方式 */}
<div dangerouslySetInnerHTML={{__html:this.state.article}}></div>
{/* 渲染列表 */}
{this.state.todos.map(todo =>{
return (
<div key={todo.id}>{todo.title}</div>
)
})}
<Like />
</Fragment>
)
}
}