React实现todolist

本文介绍了如何利用React开发一个TodoList应用。首先讲解了React的特点,包括声明式编程和数据驱动UI。接着,详细描述了开发前的准备工作,如安装和运行React项目。文章深入探讨了文件结构,特别是`todo-list`文件夹内的组件组织,强调了组件命名和渲染规则。文中还讨论了组件之间的数据传递,包括父向子和子向父的传递方式。最后,提到了React构造函数的作用以及推荐使用的插件和库。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

React特点

用于构建用户界面的 js库、框架

声明式:数据改变时,能够有效地更新并正确地渲染组件;以声明方式编写UI,使得代码更可靠,利于调试

准备工作

  1. 安装:局部安装 npx create-react-app todo-list

    npx–>npm 5.2+附带的package运行工具

  2. 运行: npm start 默认在3000端口下运行

  3. 删除src文件夹内容,更改为如图下所示

    ![src](E:\teacher-code\src.png在这里插入图片描述

todo-list文件夹

组件首字母大写

./index.js

→	作为render,渲染入口
import React from 'react'
import { render } from 'react-dom'

import App from './App'
render(
    <App />,
    document.querySelector('#root')
)

./App.js

 → 	存放最外层组件,即父组件

引入子组件后,要在render方法中return组件,首字母大写

可以使用 或两种方式渲染组件

必须使用闭合标签<></> 、

…包裹

传值,父组件-→后代组件的数据传递,通过属性传递使用特定属性值

import React, { Component } from 'react'
//没有./components/index.js文件时,引入子组件的方法
// import TodoHeader from './components/TodoHeader'
// import TodoInput from './components/TodoInput'
// import TodoList from './components/TodoList'

////有./components/index.js文件时,引入子组件的方法
import {
    TodoHeader,
    TodoInput,
    TodoList
} from './components'

export default class App extends Component {

    constructor() {
        super()
        this.state = {
            title: '待办事项列表',
            subtitle: '今日事,今日毕',
            index: 3,
            todos: [
                {
                    id: 1,
                    title: '吃饭',
                    isCompleted: false
                },
                {
                    id: 2,
                    title: '睡觉',
                    isCompleted: true
                }
            ]
        }
    }

    // 修改完成状态的方法
    completedChange = (id) => {
        console.log(this.state.index)
        // 修改状态数据,需要显式调用 setState() 方法来修改
        // setState() 是异步更新状态
        this.setState({
            todos: this.state.todos.map(todo => {
                if (todo.id === id) {
                    todo.isCompleted = !todo.isCompleted
                }
                return todo
            }),
            // index: this.state.index + 5
        }, () => {
            console.log('回调:', this.state.index)
        })

        console.log(this.state.index)
    }

    deleteTodoItem = (id) => {
        this.setState({
            todos: this.state.todos.filter(todo => todo.id !== id)
        })
    }

    addTodoItem = (title) => {
        this.setState({
            todos: [
                ...this.state.todos,
                {
                    id: this.state.index,
                    title,
                    isCompleted: false
                }
            ],
            index: this.state.index + 1
        })
    }

    render() {
        return (
            <>
                {/* 注释: */}
                <TodoHeader title={this.state.title} subtitle={this.state.subtitle}>
                    <h1>asdflkjlasfd</h1>
                    <h3>sadflk</h3>
                </TodoHeader>
                <TodoInput
                    addTodoItem={this.addTodoItem}
                />
                <TodoList
                    todos={this.state.todos}
                    completedChange={this.completedChange}
                    deleteTodoItem={this.deleteTodoItem}
                />
            </>
        )
    }
}


./components/文件夹/XX.js

 → 	存放后代组件

分别创建文件夹,每个文件夹中,设置不同的js文件,用来存放后代组件;

js文件最好命名为index.js,便于引入

传值,子组件-→父组件的数据传递,通过props.属性名或者props.children获取数据

两种写法

 //ES6写法
 state = {
        inputValue: 'abc'
    }

//普通写法
    constructor () {
        this.state = {
            inputValue: ''
        }
    }

./components/index.js

方法一:

import TodoHeader from './TodoHeader'
import TodoInput from './TodoInput'
import TodoList from './TodoList'

export {
    TodoHeader,
    TodoInput,
    TodoList
}

方法二:

as →重命名

export { default as TodoHeader } from './TodoHeader'
export { default as TodoInput } from './TodoInput'
export { default as TodoList } from './TodoList'

NOTE:

  • 修改状态===更新数据

  • 使用结构赋值方式引入的优点

      import ReactDom from 'react-dom'
      ReactDom.render()
    
      //结构赋值方式
      import { render } from 'react-dom'
      render()
    
  • JSX在react包中

  • 用数据驱动渲染,减少DOM操作。

  • 组件间的数据传输

    子组件-→父组件的数据传递 通过props.属性名或者props.children获取数据

    父组件通过属性将子组件要用的方法传递下来,在子组件中调用对应的方法,传递参数,将数据传递出去

    父组件-→后代组件的数据传递 通过属性传递使用特定属性值,状态提升到共同会用到的父组件中

  • 在 React 中,构造函数仅用于以下两种情况:

    1 通过给 this.state 赋值对象来初始化内部 state。
    2 为事件处理函数绑定实例

  • lodash

    _.cloneDeep(value)
    
    这个方法类似 _.clone,但它会递归拷贝 value。(也叫深拷贝)。
    
  • VScode中可以安装ES7插件,这样在js文件中

    输入ref+回车引入函数式组件,有state,属于无状态组件,用Hook添加

    import React from 'react'
    
    export default function App() {
        return (
            <div>
                
            </div>
        )
    }
    

    输入rcc+回车→引入类组件,无state,属于有状态组件

    import React, { Component } from 'react'
    
    export default class App extends Component {
        render() {
            return (
                <div>
                    
                </div>
            )
        }
    }
    
    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值