实时更新react项目从0开始

这个文章写的比较详细一些,是关于react项目的初学从基础创建到项目的实战,望业界大佬不要嘲笑才好。本人呢!在学习中如有什么错点,可以指出来呀,我才能吸取教训多多改正啊,望共进步!如果有辛给你们带来帮助,我也会很高兴滴!文章会实时更新

下载一个react项目

React的优点:提升开发效率、代码可维护性和可阅读性增强-

需提前检测npm 和node  因为本人配置了,所以就也不演示和解释了
npm  install -g create-react-app 下载脚手架工具
create-react-app my-app          下载项目 目录
  
cd my-app     进行到当前文件夹下
npm start       开启项目

项目目录讲解


1.yarn.lock文件 主要是项目的安装包做的一些版本号限制 无效动它(理解是什么即可)
2.README.md 这个文件是项目的说明文件 关于项目的说明 可以通过markdown语法自己写一些对项目的说明
3.package.json 属于node的包文件,关于配置,包,指令调用
4.gitignore 用git上传管理包文件的时候,做一些不想上传的包文件,即可定义在这里面
5.node_modules 环境的配置文件第三方的 node的包文件
6.public
(1) favicon.ico 打开文件,网页浏览器左上方的文件图标
(2)ndex.html 首页的html模板 manifest title网页浏览器的标题 noscript 这个是容错标签增加健壮性
(3) manifest.json
PWA serviceWorker 一起连用 定义和它是配套的
定义快捷方式的图标,网址,主题颜色
7.src 放置所有项目的源代码
(1)index.js 整个程序的 源代码的入口文件
import * as serviceWorker from ‘./serviceWorker’
serviceWorker 通过写网页的形式,做一些移动端的app应用
// 效果是:例如上线到一台具备https协议的服务器上,用户的第一次访问是必须联网的,但是一旦用户访问的页面断网了。当第二次访问的时候,会加载到第一次访问数据的那个时候
(2)App.text.js 自动化测试文件
(3)App.js 内容的编译

react组件

1.组件化 自行看对比图理解组件划分
在这里插入图片描述
1.index.js

ReactDOM.render(
//jsx
  <App />,
  // App 挂载到index.html主文件内ID名为root的节点下   就是index.html的div内展示组件内容
  document.getElementById('root')
);

2.App .js 组件

// 因为是个组件所以要引入react compontent
 //用jsx是会解析当前代码的
import React,{ Component,Fragment } from 'react';
// es6 
// import { Component } from 'react'
// 等价于
// const Component = React.Component
class App extends Component {
  render(){
  //jsx
    return (
    <Fragment>
    	 <div className="App">hello</div>
    	 <p>hello</p>
    </Fragment> 
   
    );
  }
}
export default App; //导出

最基础的jsx语法

  1. JSX语法中,如果我们要使用自己创建的组件 直接通过标签形式来直接使用即可(附加解释和vue相类似)
  2. JSX语法中,使用自己的组件,组件名的开头必须是大写英文字母 小写的一般都是原始标签
  3. 需要在组件内容内有一个最大的div包裹元素 Fragment占位符 替换div
  4. 在JSX内写注释需要用花括号进行一个包裹
  5. dangerouslySetInnerHTML={{__html: item}} 标签内容进行的转义
  6. 循环时 标签上的key={ index }
  7. import ‘./style.css’ css的引用 className 进行定义class类名
  8. label 区域聚光标的for 在react中for 就为htmlFor input引用,那么input的ID就为htmlFor的命名
  9. 事件为on然后字母大写

项目的最基本就已经完成了

接下来可以做一个TodoList的简单案例试一下

import React, { Component, Fragment } from 'react'
import './style.css'
// Fragment 替换div 占位符
class TodoList extends Component {
  // constructor最优先执行的一个函数
  constructor (props) {
    super(props)
    // this.state  组件的状态
    this.state = {
      inputValue: '',
      list: []
    }
  }

  render () {
    return (
      <Fragment>
        <div>
          {/* label 一定范围内聚焦  在react中for 就为htmlFor   事件为on然后字母大写 */}
          <label htmlFor='inserAea'>
            输入内容
          </label>
          <input
            id='inserAea'
            className='input'
            value={this.state.inputValue}
            onChange={this.handleInputChange.bind(this)} />
          <button onClick={this.handleBtnClick.bind(this)}>
            提交
          </button>
        </div>
        <ul>
          {/* dangerouslySetInnerHTML 输入框内的标签不显示,防XSS攻击的可能 第一个花括号意为花括号内一定跟着一个js的表达式  第二个花括号意为着js的对像 */}
          {this.state.list.map((item, index) => {
             return (
               <li key={index} onClick={this.handleItemDelete.bind(this, index)} dangerouslySetInnerHTML={{__html: item}}>
               </li>
             )
           })}
        </ul>
      </Fragment>
    )
  }

  handleInputChange (e) {
    // 获取state内的值 需要用setState进行获取
    // this指向问题可以用bind来进行改变即可
    this.setState({
      inputValue: e.target.value
    })
  }

  handleBtnClick () {
    // ...this.state.list  展开运算符  把以前数据的内容展开,然后产生一个全新的数组  
    this.setState({
      list: [...this.state.list, this.state.inputValue],
      // 并且清空inputValue
      inputValue: ''
    })
  }

  handleItemDelete (index) {
    // state 不允许直接修改任何内容,可以拷贝出来进行修改后附值
    const list = [...this.state.list]
    list.splice(index, 1)
    this.setState({
      list: list
    })
  }
}

export default TodoList

进行TodoList的拆分

  1. 父组件向子组件 传值属于运用属性的形式进行传值 既可以传递数据,又可以传递方法 例如content={item} deleteItem={this.handleItemDelete.bind(this)} bind(改变this指向的)
  2. 子组件接受通过this.props.(传递的值)来接收 当要改变父组件方法的this指向做一次绑定

父组件 TodoList

  import React, { Component, Fragment } from 'react'
import TodoItem from './TodoItem'
import './style.css'
class TodoList extends Component {
  constructor (props) {
    super(props)
    this.state = {
      inputValue: '',
      list: []
    }
  }

  render () {
    return (
      <Fragment>
        <div>
          <label htmlFor='inserAea'>
            输入内容
          </label>
          <input
            id='inserAea'
            className='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 (
               <div>
                 <TodoItem content={item} index={index} deleteItem={this.handleItemDelete.bind(this)} />
               </div>
             )
           })
          }
        </ul>
      </Fragment>
    )
  };

  handleInputChange (e) {
    this.setState({
      inputValue: e.target.value
    })
  };

  handleBtnClick () {
    this.setState({
      list: [...this.state.list, this.state.inputValue],
      inputValue: ''
    })
  };

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

export default TodoList

子组件 接收父组件传值TodoItem

import React , { Component } from 'react'
class TodoItem extends Component {

  constructor(props){
      super(props);
      this.handleClick=this.handleClick.bind(this);
  }

  render () {
    return (
      <div onClick={this.handleClick}>
        {this.props.content}
      </div>
    )
  }
  handleClick () {
      this.props.deleteItem(this.props.index)
  }
}
export default TodoItem

优化代码

父组件

 import React, { Component, Fragment } from 'react'
import TodoItem from './TodoItem'
import './style.css'
class TodoList extends Component {
  constructor (props) {
    super(props)
    this.state = {
      inputValue: '',
      list: []
    }
    // this的指向放在顶部即可
    this.handleInputChange = this.handleInputChange.bind(this)
    this.handleBtnClick = this.handleBtnClick.bind(this)
    this.handleItemDelete = this.handleItemDelete.bind(this)
  }

  render () {
    return (
      <Fragment>
        <div>
          <label htmlFor='inserAea'>
            输入内容
          </label>
          <input
            id='inserAea'
            className='input'
            value={this.state.inputValue}
            onChange={this.handleInputChange} />
          <button onClick={this.handleBtnClick}>
            提交
          </button>
        </div>
        <ul>
          {this.getTodoItem()}
        </ul>
      </Fragment>
    )
  }

  // 简洁代码化
  getTodoItem () {
    return this.state.list.map((item, index) => {
      return (
        <div key={index}>
          <TodoItem content={item} index={index} deleteItem={this.handleItemDelete} />
        </div>
      )
    })
  }

  handleInputChange (e) {
    // 使用函数形成异步,就对value值进行一个保存附值
    const value = e.target.value
    this.setState(() => ({
      inputValue: value
    }))
  }

  handleBtnClick () {
    // prevState 等价于之前接收的原数据
    this.setState((prevState) => ({
     list: [...prevState.list,prevState.inputValue],
      inputValue: ''
    }))
  // this.setState({
  //   list: [...this.state.list, this.state.inputValue],
  //   inputValue: ''
  // })
  }

  handleItemDelete (index) {
    // 可以形成一个函数体在函数体内做改变
    this.setState((prevState) => {
      const list = [...prevState.list]
      list.splice(index, 1)
      return {list}
    })
  // this.setState({
  //   list: list
  // })
  }
}

export default TodoList

子组件

import React , { Component } from 'react'
class TodoItem extends Component {

  constructor (props) {
    super(props)
    this.handleClick = this.handleClick.bind(this)
  }

  render () {
    const { content } = this.props
    return (
      <div onClick={this.handleClick}>
        {content}
        {/* {this.props.content} */}
      </div>
    )
  }
  handleClick () {
    const { deleteItem, index } = this.props
    deleteItem(index)
  // this.props.deleteItem(this.props.index)
  }
}
export default TodoItem

围绕react衍生出的思考

  1. 声明式开发 减少了代码量
  2. 可以与其它框架并存
  3. 组件化
  4. 单项数据流 父组件可以向子组件传数据,但子组件绝对不能更改父组件的数据
  5. 视图层框架 大型项目时,就需要引入redux数据层框架
  6. 函数式编程

安装React 开发调试工具

1.打开浏览器
2.浏览器右侧的三个点点开
3.点击 更多工具
4.点击 扩展程序
5.点击左上角扩展程序
6.点击最下面的Chrome网上应用店
7.需要打开翻墙软件
8.搜索react 出现React Developer Tools 点击安装

PropTypes与DefaultProps

也可自行观看文档进行理解

需要引入propTypes 
import PropTypes from 'prop-types'
// 意思就是对TodoItem这个组件对父组件传递过来的值做的一个属性的检验  isRequired表示检测父组件向子组件传值也必须传递
TodoItem.propTypes = {
  test: PropTypes.string.isRequired,
// 可以是字符串类型也可以是数字类型
// 多种验证时 PropTypes.arrayOf(PropTypes.string, PropTypes.number) 表示数组的组成或者怎么怎么样
  // oneOfType 表示以下类型中的一个 PropTypes.arrayOf([PropTypes.string, PropTypes.number])
  content:PropTypes.string,
  deleteItem: PropTypes.func,
  index: PropTypes.number
}

const { content,test } = this.props
// 组件内部定义的默认值
TodoItem.defaultProps = {
  test: 'hello world'
}

Props,state与render函数的关系

// 当组件的state或者props发生改变的时候,render函数就会重新的执行
//1. 当父组件的render函数被运行时,它的子组件的render都将被重新运行一次
//2.子组件的props接收也发生了改变

什么是虚拟DOM?

虚拟DOM中的Diff算法

React中ref的使用

之前用e.target来获取DOM元素可以使用ref来获取
 ref={(input)=>{this.input=input}} 添加在需要获取值的标签上

例子:
<ul ref={(ul) => { this.ul = ul}}>
          {this.getTodoItem()}
   </ul>

 handleBtnClick () {
    // this.setState是异步的,但是它提供了一个第二参数的函数内
    this.setState((prevState) => ({
      list: [...prevState.list, prevState.inputValue],
      inputValue: ''
    }), () => {
      // querySelectorAll('div') 查找所有的div元素
      console.log(this.ul.querySelectorAll('div').length)
    })
  }

Reac的生命周期函数

  1. 生命周期函数指在某一个时刻组件会自动调用执行的函数
  2. render
  3. construtor 不是react 独有的,是es6附带的 不归类到react生命周期内
 // 在组件即将挂载到页面的时刻自动执行
  componentWillMount () {
    console.log('componentWillMount')
  }

  // 在组件被挂载到页面之后,自动被执行
  componentDidMount () {
    console.log('componentDidMount')
  }
  // 在组件被更新之前,自动被执行  要求返回结果 是一个布尔值 true或者false
  shouldComponentUpdate () {
    console.log('shouldComponentUpdate')
    return true
  }
  //  组件被更新之前它会自动执行,但是他在shouldComponentUpdate之后被执行
  // 如果 shouldComponentUpdate返回true它才执行 返回false就不会被执行  
  componentWillUpdate () {
    console.log('componentWillUpdate')
  }
  // 在有props参数的时候才会被执行
  // 一个组件要从父组件接受参数
  // 如果这个组件第一次存在于父组件中,不会执行
  // 如果这个组件之前已经存在于父组件中,才会执行
  componentWillReceiveProps () {
    console.log('componentWillReceiveProps')
  }
  // 当这个组件即将被从页面中剔除的时候,才会被执行
  componentWillUnmount () {
    console.log('componentWillUnmount')
  }

React生命周期函数的使用场景

当数据提交时才会改变值  性能的优化
shouldComponentUpdate (nextProps, nextState) {
    if (nextProps.content !== this.props.content) {
      return true
    }else {
      return false
    }
  }

接口的调用 可以下载axios组件
npm install axios
componentDidMount(){
    axios.get('/api/todolist').then(()=>{
      alert('12')
    }).catch(()=>{
      alert('235')
    })
  }

使用Charles进行接口数据的模拟

Redux概念简述

Redux的工作流程

使用Antd实现TodoList页面布局

创建redux中的store

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1. 为了搭建一个React项目,首先要确保你的开发环境已经配置好了。你需要安装Node.js和npm(Node包管理器)。 2. 使用命令行工具进入你想要保存项目的文件夹,并执行以下命令来创建一个新的React应用: ```shell npx create-react-app my-app ``` 这将使用create-react-app脚手架工具创建一个新的React应用,并在my-app文件夹中初始化项目结构。 3. 进入my-app文件夹,并启动开发服务器: ```shell cd my-app npm start ``` 这将启动一个本地开发服务器,并在浏览器中打开http://localhost:3000以查看你的React应用。 4. 现在你可以开始编写你的React组件了。你可以创建函数组件或类组件来定义你的UI。函数组件是一个纯函数,接收props对象并返回一个React元素;而类组件需要继承React.Component,并实现一个render函数来返回React元素。 5. 如果你需要在组件之间进行通信,可以使用Redux这样的状态管理库。Redux可以帮助你管理全局的状态,并使不同组件之间共享数据变得更加容易。你可以使用npm来安装Redux和相关的库: ```shell npm install redux react-redux ``` 然后,你可以在你的应用中创建Redux的store,并通过Provider组件将它提供给整个应用。你可以使用connect函数来连接你的组件,使其能够访问Redux中的状态。 6. 最后,你可以使用第三方UI库来加快你的开发速度。Ant Design是一个流行的React UI框架,它提供了丰富的组件和样式,可以帮助你快速构建漂亮的用户界面。你可以使用npm来安装Ant Design: ```shell npm install antd ``` 然后,你可以在你的组件中引入Ant Design的组件,并使用它们来构建你的UI。Ant Design的文档提供了详细的使用说明和示例代码,可以帮助你更好地了解和使用该框架。 以上是从0到1搭建一个React项目的一般步骤。你可以根据实际需求和项目要求进行相应的调整和扩展。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [REACT实战项目从0到1搭建(仅供参考)](https://blog.csdn.net/qq_31851435/article/details/121740400)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [react-从0到1新建react项目](https://blog.csdn.net/weixin_40220492/article/details/127145343)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值