Skip to content
本页目录

React 入门

image-20230501081946464

1.用HTML引入CDN创建React项目

1.1新建如下index.html

html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="shortcut icon" href="#">
    <script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
    <script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
  </head>
  <body>
  </body>
</html>

1.2指定渲染根组件

html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width= , initial-scale=1.0">
  <title>React入门</title>
  <script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
  <script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>

</head>
<body>
  <div id="root"></div>
  <script>
    const root = ReactDOM.createRoot(document.getElementById("root")) //创建根组件
    root.render(<h1>宝可梦</h1>)  //这个可以用根组件的render方法,渲染子组件
  </script>
</body>
</html>

DANGER

此时打开页面会报错.因为js识别不了render中的jsx的语法

image-20230501081258024

解决方案

引入babel

html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <title>React入门</title>
  <script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
  <script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
  <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>

</head>
<body>
  <div id="root"></div>
  <script  type="text/babel">
    const root = ReactDOM.createRoot(document.getElementById("root")) //创建根组件
    root.render(<h1>宝可梦</h1>)  //这个可以用根组件的render方法,渲染子组件
  </script>
</body>
</html>

效果就加载出来了

image-20230501082228706

2.将render中的标签抽离成类组件

2.1所有的代码写入render函数中就太麻烦了,而render可以传入组件 如下

jsx
<script  type="text/babel">
    const root = ReactDOM.createRoot(document.getElementById("root")) //创建根组件
    root.render(<App />)
  </script>

那App组件是如何创建的呢?

创建组件可以有两种形式

  • 类组件
  • 函数组件

类组件是React老版本一直在使用的方式,也体现了React的核心运作原理,而函数式组件是后来才有的方式,也越来越流行

我们先看类组件如何创建

jsx
<body>
  <div id="root"></div>
  <script  type="text/babel">
    const root = ReactDOM.createRoot(document.getElementById("root")) //创建根组件
    class App extends React.Component{	//创建App类组件
      render(){
        return <h1>宝可梦</h1>
      }
    }
    root.render(<App />)
  </script>
</body>

2.2常见的两个错误

render函数return 返回的jsx语法是用()包裹而不是{}包裹

DANGER

错误写法

jsx
 class App extends React.Component{	//创建App类组件
      render(){
        return {
            <h1>宝可梦</h1>
        }
      }
    }

SUCCESS

正确写法

jsx
 class App extends React.Component{	//创建App类组件
      render(){
        return (
            <h1>宝可梦</h1>
        )
      }
    }

render返回多个标签没有根元素

DANGER

错误写法

jsx
 class App extends React.Component{	//创建App类组件
      render(){
        return {
            <h1>宝可梦</h1>
        	<input type="search">
        }
      }
    }

SUCCESS

正确写法

jsx
class App extends React.Component{	//创建App类组件
     render(){
       return {
       <div>
           <h1>宝可梦</h1>
       	<input type="search" />
       </div>
       }
     }
   }

2.3jsx写js,并用插值表达式html中遍历定义的数组为列表元素

jsx
 <script  type="text/babel">
    const root = ReactDOM.createRoot(document.getElementById("root")) //创建根组件
    const pokemons = ["皮卡丘","杰尼龟"]	//定义js变量
    class App extends React.Component{
      render(){
        return (
          <div>
              <h1>宝可梦</h1>
              <input type="search" />
              <ul>
                <li>{pokemons[0]}</li>				//{}为插值语法 插入定义的变量
                <li>{pokemons[1]}</li>
              </ul>
          </div>
        )
      }
    }
    root.render(<App />)
  </script>

image-20230501085520699

改进 如何循环输出

用map的方式

jsx
const root = ReactDOM.createRoot(document.getElementById("root")) //创建根组件
const pokemons = ["皮卡丘","杰尼龟"]
class App extends React.Component{
      render(){
        return (
          <div>
              <h1>宝可梦</h1>
              <input type="search" />
              <ul>
                {pokemons.map(pokemon=><li>{pokemon}</li>)}
              </ul>
          </div>
        )
      }
    }
    root.render(<App />)

改进 为了方便抽离 如何吧变量定义在类中,并且数组的状态能变动态响应到html标签并渲染

jsx
const root = ReactDOM.createRoot(document.getElementById("root")) //创建根组件
    class App extends React.Component{
      constructor(){
        super()
        this.state= {
          pokemons : ["皮卡丘","杰尼龟"]
        }
      }
      render(){
        return (
          <div>
              <h1>宝可梦</h1>
              <input type="search" />
              <ul>
                {this.state.pokemons.map(pokemon=><li>{pokemon}</li>)}
              </ul>
          </div>
        )
      }
    }
    root.render(<App />)

3.调用API

通常数据不是写死的 那么我们如何去调用api并且在加载完DOM元素后把数据渲染上去

首选componentDidMount的方法是相当于mounted

之后 this.setState()是为了动态更新 如果直接赋值是不会更新视图的

jsx
class App extends React.Component{
      constructor(){
        super()
        this.state= {
          pokemons : ["皮卡丘","杰尼龟"]
        }
      }
      componentDidMount(){
        fetch("https://pokeapi.co/api/v2/pokemon")
        .then(res => res.json())
        .then(json => {
          json.results.map((result, index) => {
            result.id = index + 1;
          })
          this.setState(
          () => {
            return { 
              pokemons: json.results,
            };
          },
          () => { //为了能反映出设置后的具体值 不然因为this.setState是回调函数那么就会返回初始值 ["皮卡丘","杰尼龟"]
            console.log( this.state );
          }
        );
        })
      }
      render(){ //不能把对象放入插值语句中
        return (
          <div>
              <h1>宝可梦</h1>
              <input type="search" />
              <ul>
                {this.state.pokemons.map(pokemon=><li>{pokemon.name}</li>)}
              </ul>
          </div>
        )
      }
    }

image-20230501091130671

3.1key值报错问题

image-20230501091314447

解决 key值问题

jsx
 render(){ //不能把对象放入插值语句中
        return (
          <div>
              <h1>宝可梦</h1>
              <input type="search" />
              <ul>
                {this.state.pokemons.map(pokemon=><li key={pokemon.url}>{pokemon.name}</li>)}
              </ul>
          </div>
        )
      }

image-20230501092007437

但是加了还是报错 因为执行顺序 先构造 然后render 之后再mounted再render

这样就算后来有了key值 但因为初始值的时候就要调用 所以会发生报错

image-20230501091839692

解决方案

把初始值设置为[]

jsx
constructor(){
        super()
        this.state= {
          pokemons : []
        }
      }

image-20230501092241577