Appearance
React 入门
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的语法
解决方案
引入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>
效果就加载出来了
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>
改进 如何循环输出
用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>
)
}
}
3.1key值报错问题
解决 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>
)
}
但是加了还是报错 因为执行顺序 先构造 然后render 之后再mounted再render
这样就算后来有了key值 但因为初始值的时候就要调用 所以会发生报错
解决方案
把初始值设置为[]
jsx
constructor(){
super()
this.state= {
pokemons : []
}
}