在React基础中,我们需要完成如下的学习

  • 脚手架使用 。
  • jsx
  • 组件,
  • 状态,
  • 事件,
  • 案例

一,入门&&脚手架

React是什么

是什么?

  1. 一个构件V的层面,不是一个完成的MVC,一个构建用户界面的库

特点?

  1. 声明式:你只需要描述UI长什么样就好了
  2. 基础组件: 最重要的内容,
  3. 到处跑:原生应用可以,vr可以 ,

基础的使用

是安装脚手架

  1. npm i recat rect-dom
  2. 第一个是核心包,提供创建元素,组件等功能
  3. 第二个是一个提供DOM相关的包
  1. 引入recat 还有 recat-dom
  2. 创建recat元素
  3. 渲染recat到页面中

    1. <body>
    2. <div id="app"></div>
    3. </body>
    4. <!-- 1. 引入两个包 -->
    5. <script src="./node_modules/react/umd/react.development.js"></script>
    6. <script src="./node_modules/react-dom/umd/react-dom.development.js"></script>
    7. <!-- 2. 挂载点 -->
    8. <!-- 3. 开始创建 -->
    9. <script>
    10. // 定义,注意第一个是标签,第二个是参数,第三个开始都是其子节点
    11. const title = React.createElement( 'h1',null,'hello ', React.createElement( 'span',null,'hehhe' ) )
    12. // 挂载,
    13. ReactDOM.render( title,document.getElementById('app') )
    14. </script>

    脚手架

    以前我们都是直接使用cli但是我们都不知道为什么要使用cli接下里,听老夫吹水一波

    1. 是现代开发必备的
    2. 充分的利用了各种工具webpack bable eslint等,辅助开发
    3. 零配置,无序配置,关注的是代码业务 而不是配置
  4. 执行命令创建项目

    1. npx create-react-app my-app
    2. npx 5.2的东西,npm不需要安装脚手架,可以直接用。create-react-app是脚手架的名称
  5. 运行 start就好了

    在Reatc脚手架项目中配置项目

    实际上的效果是没有任何变化的

  1. import React from 'react'
  2. import ReactDOM from 'react-dom' // z注意,如果你做的原生app用的就是零个RN去渲染,而不是ReactDOM
  3. const title = React.createElement( 'h1',null,'hellwe!')
  4. // 注意这个root是再public下的index中的根元素的
  5. ReactDOM.render( title,document.getElementById('root') )

二、JSX 核心

首先我们来介绍如下的学习目标

  1. jsx基础的使用
  2. jsx中的js表达式
  3. jsx中的条件渲染
  4. jsx中的列表渲染
  5. jsx中的演示处理
  6. 手写太累了?建议试一下vs的提示代码插件,完美提升开发速度

jsx基础使用

实际上就是js版的html,jsx是JavaScript xml 表示在js中写xml和html内容

  1. import React from 'react'
  2. import ReactDOM from 'react-dom'
  3. // const title = React.createElement( 'h1',null,'hellwe!')
  4. // 使用jsx
  5. const title = <h1>hellow jsx</h1>
  6. // 注意这个root是再public下的index中的根元素的
  7. ReactDOM.render( title,document.getElementById('root') )

为什么脚手架中 直接写可以html?

注意脚手架内部做了转化bable @bable/preset-reacle

注意事项:在jsx中注意实现

  1. {}中可以使用js语法
  2. jsx自己页是一个变量 可以插入
  3. jsx中对象是一个例外,不能插入
  4. 注意{}中不能出现体语句,if/for ```typescript

const name = ‘zs’ const age = 18 const gender = ‘man’

const div = (

我是一个div
)

const title = ( // 注意属性名需要用小驼峰 // 注意一些特殊的属性名,class => calssName for => htmlFor。。。。 // 建议使用小括号包裹起来jsx

  1. 姓名:{name}
  2. <br />
  3. 年龄:{age}
  4. <br />
  5. 行呗:{gender + 5}
  6. {div}

)

  1. <a name="4OQIw"></a>
  2. ### 条件渲染& 列表渲染
  3. > 注意,这个就是React中的特点,用正确的方式做正确的事情,
  4. >
  5. > 1. 使用函数去判断,完成条件渲染
  6. > 1. 使用map方法去做隐射,注意要谢上key
  7. ```javascript
  8. const loadData = () => {
  9. return isloading && (<div>显示完成~</div>)
  10. }
  11. // 列表渲染
  12. const list = [
  13. {id:1,name:'zs'},
  14. {id:2,name:'ls'},
  15. {id:3,name:'ww'}
  16. ]
  17. const title = (
  18. <div>
  19. <h2>
  20. {loadData()}
  21. </h2>
  22. <div>
  23. <ul>
  24. {list.map( v => <li key={v.id} > {v.name} </li> )}
  25. </ul>
  26. </div>
  27. </div>
  28. )

jsx中的样式绑定

实际上非常的容易,两种方式styel内嵌还有映入文件,挂类名的

  1. import './index.css'
  2. const text= (
  3. <div className="title" style={{'color':'red','backgroundColor':'pink'}}>
  4. 点击
  5. </div>
  6. )

总结 Resct完全使用js语言,来编写ui,而不是找轮子增强HTML功能!在React中能用js的地方绝对不增加新的语法

三、组件

react中的组件的非常重要的东西。

基础的使用

组价就是recat的核心,独立性,组合型,可组合可以复用

  • 使用组件有两种方式,函数式(不常用),箭头函数也是ok的,但是后续有问题的,我们后面再说,

    为什么要使用大写?因为可以区分是组件还是元素

  1. function Hellow () {
  2. return ( <h1>helloe 我是一个函数组件</h1> )
  3. }
  4. // 注意这个root是再public下的index中的根元素的
  5. ReactDOM.render( <Hellow />,document.getElementById('root') )
  • 使用类来创建(常用)
  • React.Component必须继承 必须由返回值,必须由值 ```javascript // React.Component必须继承 必须由返回值,必须由值 class Hello extends React.Component { render() { return (

    是我了,没错了!

    ) } }

// 注意这个root是再public下的index中的根元素的 ReactDOM.render( ,document.getElementById(‘root’) )

  1. <a name="tMwOq"></a>
  2. ### 单独抽离组件
  3. > 这个很重要,直接抽离出去就好了,做起来也非常的好,直接抽出来就好了
  4. hello.js
  5. ```javascript
  6. import React from 'react'
  7. class Hello extends React.Component {
  8. render() {
  9. return ( <h1>是我了,没错了!</h1> )
  10. }
  11. }
  12. export default Hello
  13. // 这样就好了
  14. import Hello from './hello'
  15. // 注意这个root是再public下的index中的根元素的
  16. ReactDOM.render( <Hello />,document.getElementById('root') )

事件处理&事件对象

  1. 我们先来看看如何进行事件的绑定,事件的搬定是非常简单的,只需要

    注意啊。class组件是this 而,函数组件是没有this的!

  1. import React from 'react'
  2. class Hello extends React.Component {
  3. hander(){
  4. console.log('点击了我!');
  5. }
  6. render() {
  7. // 这里需要注意的点是onclick必须是小驼峰的
  8. return ( <button onClick={this.hander}> 点击我</button> )
  9. }
  10. }
  11. export default Hello
  1. 事件对象
    1. hander(e){
    2. // 注意这个e是跨平台的!,这个e也叫“作合成事件”
    3. e.preventDefault()
    4. console.log('点击了我!');
    5. }

    四 、状态

    有、无状态state

事实上,有非常简单的理解就是有状态组件就是指的是class的组件
image.png

状态到底是什么?

实际上状态就是data数据(类似于vue中的data)

  1. 我们来定义一个数据 ```javascript

class Hello extends React.Component { // constructor(){ // super()

// this.state = { // count = 0 // } // } state = { count : 0 }

hander = (e) => { // 注意这里的this问题 箭头函数可以,bind也可以 this.setState({ count : this.state.count + 1 }) } render() { // 这里需要注意的点是onclick必须是小驼峰的

  1. return (
  2. <div>
  3. <h1>{this.state.count}</h1>
  4. <button onClick={this.hander}> 点击我可以+1</button>
  5. </div> )
  6. }

}

  1. 2. 我们来改变一个数据(React中默认支持响应mvvm 详细的代码如上已经给出
  2. <a name="3ToQr"></a>
  3. ###
  4. <a name="Fgpw0"></a>
  5. ## 五、事件
  6. <a name="X1v6L"></a>
  7. ## 受控组件还有非受控组件
  8. > 所谓的受控组件,就是有recatestate控制的组件,默认的情况下,html有自己的状态,比如input框,可以自己输入,
  9. > 但是recate希望由自己的state控制,于是就有了受控组件,实现一个受控组件
  10. 1. 实现一个最简单的受控组件input进行双向的数据绑定
  11. ```javascript
  12. state = {
  13. text :'',
  14. }
  15. // 事件
  16. hander = (e) => { // 注意这里的this问题
  17. this.setState({
  18. text : e.target.value,
  19. })
  20. }
  21. <div>
  22. <h1>{this.state.text}</h1>
  23. <input value={this.state.text} onChange={this.hander}></input>
  24. </div>
  1. 实现多个受控的组件 ```javascript import React from ‘react’

class Hello extends React.Component { // constructor(){ // super()

// this.state = { // count = 0 // } // } state = { text :’’, content:’’, city:’bj’, checked:false }

// 事件 hander = (e) => { // 注意这里的this问题 this.setState({ text : e.target.value,

  1. })

}

handerContet = (e) => { // 注意这里的this问题 this.setState({ content : e.target.value,

  1. })

}

handerCity = (e) => { // 注意这里的this问题 this.setState({ city : e.target.value,

  1. })

}

handerCheckebox = (e) => { // 注意这里的this问题 this.setState({ checked : e.target.checked,

  1. })

} render() { return (

{/ input简单的受控组件 /}

{this.state.text}

{/ 富文本受控组件 /}
{/ 下拉选择受控组件 /}
) } }

export default Hello

  1. <a name="d3Rw1"></a>
  2. ### 多表单元素的优化
  3. > 使用一个处理程序,处理多个事件,实际上,这个也是一个造轮子的过程,我们给选框,打一个记号,然后根据记号,改变值
  4. ```javascript
  5. import React from 'react'
  6. class Hello extends React.Component {
  7. // constructor(){
  8. // super()
  9. // this.state = {
  10. // count = 0
  11. // }
  12. // }
  13. state = {
  14. text :'',
  15. content:'',
  16. city:'bj',
  17. checked:false
  18. }
  19. // 事件
  20. handerFrom = (e) => { // 注意这里的this问题
  21. let target = e.target
  22. let value = target.type === "checkbox"
  23. ? target.checked
  24. : target.value
  25. let name = target.name
  26. this.setState({
  27. [name] : value
  28. })
  29. }
  30. render() {
  31. return (
  32. <div>
  33. {/* input简单的受控组件 */}
  34. <div>
  35. <h1>{this.state.text}</h1>
  36. <input name="text" value={this.state.text} onChange={this.handerFrom}></input>
  37. </div>
  38. {/* 富文本受控组件 */}
  39. <div>
  40. <textarea name="content" value={this.state.content} onChange={this.handerFrom}></textarea>
  41. </div>
  42. {/* 下拉选择受控组件 */}
  43. <div>
  44. <select name="select" value={this.state.city} onChange={this.handerFrom}>
  45. <option value="sh">上海</option>
  46. <option value="gz">官洲</option>
  47. <option value="bj">北京</option>
  48. </select>
  49. </div>
  50. </div> )
  51. }
  52. }
  53. export default Hello

非受控组件

这个知识点,我们了解就好了,在react中是不推荐直接操作dom的

image.png

React中的组件基础总结

基础第一部分-基础Code - 图3

六、综合练习

  1. 渲染列表

列表渲染,条件渲染

有关于列表的渲染还是非常的简单的,只需要渲染遍历map就好了

  1. import React from 'react'
  2. class Commont extends React.Component {
  3. state = {
  4. comment:[
  5. { id:1, name:'jack', content:'沙发!!!' },
  6. { id:2, name:'roes', content:'heieh' },
  7. { id:3, name:'tom', content:'板凳' },
  8. { id:4, name:'JRET', content:'有点意思~' }
  9. ]
  10. }
  11. render() {
  12. return (
  13. <div className="app">
  14. {/* 顶部盒子 */}
  15. <div>
  16. <input className="user" type='text' placeholder="请输入评论人" />
  17. <br />
  18. <textarea
  19. className="content"
  20. cols="30"
  21. rows="10"
  22. placeholder="请输入评论内容"
  23. />
  24. <br />
  25. <button>发布评论</button>
  26. </div>
  27. {/* 中间盒子 */}
  28. <div className="no-comment">暂无评论,快去评论吧</div>
  29. {/* 品论额列表 */}
  30. //核心代码
  31. <ul>
  32. {
  33. this.state.comment.map(item => (
  34. <li key={item.id}>
  35. <h3>评论人: {item.name} </h3>
  36. <p> 评论内容:{item.content} </p>
  37. </li>
  38. ) )
  39. }
  40. </ul>
  41. </div>
  42. )
  43. }
  44. }
  45. export {Commont}

做好写死的渲染之后,现在我们“活起来”尝试使用一下条件渲染吧~( 又是一个造轮子的过程,注意啊,我们不允许在jsx中出现语句,形入if/else不允许出现)

  1. // 这里只是给出核心代码,三元表达式那是真的香啊!!!
  2. {
  3. this.state.comment.length === 0
  4. ? (
  5. <div className="no-comment">暂无评论,快去评论吧</div>
  6. )
  7. : (
  8. <ul>
  9. {
  10. this.state.comment.map(item => (
  11. <li key={item.id}>
  12. <h3>评论人: {item.name} </h3>
  13. <p> 评论内容:{item.content} </p>
  14. </li>
  15. ) )
  16. }
  17. </ul>
  18. )
  19. }

功能是可以并且允许 无限的优化的。接下来,我们丢带方法里去

  1. renderList() {
  2. if( this.state.comment.length === 0 ){
  3. return ( <div className="no-comment">暂无评论,快去评论吧</div> )
  4. }
  5. return (
  6. this.state.comment.map(item => (
  7. <li key={item.id}>
  8. <h3>评论人: {item.name} </h3>
  9. <p> 评论内容:{item.content} </p>
  10. </li>
  11. ) )
  12. )
  13. }
  1. 发布评论功能

受控组件,更新状态

准备数据,实现受控组件,注意这里的 属性名表达式(ES6的语法),这个也是非常重要的一点!

  1. // 注意,这里只是列举了一些核心的代码块
  2. state = {
  3. comment:[
  4. { id:1, name:'jack', content:'沙发!!!' },
  5. { id:2, name:'roes', content:'heieh' },
  6. { id:3, name:'tom', content:'板凳' },
  7. { id:4, name:'JRET', content:'有点意思~' }
  8. ],
  9. userName:'',
  10. userContent:''
  11. }
  12. // 首先双向的数据搬定方式,注意this问题!
  13. handleChange = (e) => {
  14. const { name,value } = e.target
  15. this.setState({
  16. [name]:value
  17. })
  18. }
  19. // DOM的互动
  20. <div className="app">
  21. <div>
  22. <input
  23. className="user"
  24. type='text'
  25. placeholder="请输入评论人"
  26. value={userName}
  27. name='userName'
  28. onChange={this.handleChange}
  29. />
  30. <br />
  31. <textarea
  32. className="content"
  33. cols="30"
  34. rows="10"
  35. placeholder="请输入评论内容"
  36. value={userContent}
  37. name='userContent'
  38. onChange={this.handleChange}
  39. />

接下俩的事情久是水到渠成了!获取数据更新数组列表就完事了! image.png

  1. // 这里只是列举出几个核心的代码.注意这里的结构赋值很重要!,数组的往前的添加方法666的写法
  2. // 点击按钮添加数据
  3. addCommet = () => {
  4. const { userContent,userName,comment } = this.state
  5. let newComment = [ {
  6. id:comment[comment.length-1].id + 1, // id自增
  7. name:userName,
  8. content:userContent
  9. } ,...comment ]
  10. this.setState({
  11. comment:newComment
  12. })
  13. }
  14. <button onClick={this.addCommet}>发布评论</button>

完善组件的功能

  1. // 点击按钮添加数据
  2. addCommet = () => {
  3. const { userContent,userName,comment } = this.state
  4. // 做一些数据校验的工作
  5. if(userContent.trim() === '' || userName.trim() === '' ){
  6. alert('请输入评论人/品论内容')
  7. return
  8. }
  9. let newComment = [ {
  10. id:Math.random(),
  11. name:userName,
  12. content:userContent
  13. } ,...comment ]
  14. this.setState({
  15. comment:newComment,
  16. // 优化,点击之后清空表单
  17. userContent:'',
  18. userName:''
  19. })
  20. }

代码集合

渲染的逻辑这里就不写了,直接拿出去渲染就是了

  1. import React from 'react'
  2. class Commont extends React.Component {
  3. state = {
  4. comment:[
  5. { id:1, name:'jack', content:'沙发!!!' },
  6. { id:2, name:'roes', content:'heieh' },
  7. { id:3, name:'tom', content:'板凳' },
  8. { id:4, name:'JRET', content:'有点意思~' }
  9. ],
  10. userName:'',
  11. userContent:''
  12. }
  13. // 条件渲染列表组件
  14. renderList () {
  15. if( this.state.comment.length === 0 ) {
  16. return ( <div className="no-comment">暂无评论,快去评论吧</div> )
  17. }
  18. return (
  19. this.state.comment.map(item => (
  20. <li key={item.id}>
  21. <h3>评论人: {item.name} </h3>
  22. <p> 评论内容:{item.content} </p>
  23. </li>
  24. ) )
  25. )
  26. }
  27. // 首先双向的数据搬定方式,注意this问题!
  28. handleChange = (e) => {
  29. const { name,value } = e.target
  30. this.setState({
  31. [name]:value
  32. })
  33. }
  34. // 点击按钮添加数据
  35. addCommet = () => {
  36. const { userContent,userName,comment } = this.state
  37. // 做一些数据校验的工作
  38. if(userContent.trim() === '' || userName.trim() === '' ){
  39. alert('请输入评论人/品论内容')
  40. return
  41. }
  42. let newComment = [ {
  43. id:Math.random(),
  44. name:userName,
  45. content:userContent
  46. } ,...comment ]
  47. this.setState({
  48. comment:newComment,
  49. // 优化,点击之后清空表单
  50. userContent:'',
  51. userName:''
  52. })
  53. }
  54. // 正式的返回值
  55. render() {
  56. // 先进行结构。使得结构看起来更加的清晰
  57. const { userName,userContent } = this.state
  58. return (
  59. <div className="app">
  60. <div>
  61. <input
  62. className="user"
  63. type='text'
  64. placeholder="请输入评论人"
  65. value={userName}
  66. name='userName'
  67. onChange={this.handleChange}
  68. />
  69. <br />
  70. <textarea
  71. className="content"
  72. cols="30"
  73. rows="10"
  74. placeholder="请输入评论内容"
  75. value={userContent}
  76. name='userContent'
  77. onChange={this.handleChange}
  78. />
  79. <br />
  80. <button onClick={this.addCommet}>发布评论</button>
  81. </div>
  82. {this.renderList()}
  83. </div>
  84. )
  85. }
  86. }
  87. export {Commont}