React教程(详细)
文章目录
- React教程(详细)
- 1:创建一个 React 程序
- 2:开始
- 3:使用 class 和 function 创建组件
- 3.1:function 组件
- 3.2:class 组件
- 4:生命周期
- 5:state
- 6:事件处理
- 6.1:方式一:不绑定this
- 6.2:方式二:绑定this,返回函数调用
- 6.3:方式三:绑定this,使用bind绑定
- 7:条件渲染
- 8:列表
- 9:受控组件值的实时修改
React是一个用于构建用户界面的 JavaScript 库。
1:创建一个 React 程序
如果你不熟悉es6或nodeJs也没关系,此数实例都采用引入 js 文件方式开发react程序,可以直接创建html文件复制内容进去,在浏览器打开运行。首先创造你的兴趣,这才是最重要的。
有两种方式创建 React 程序。
第一种:引入 js 文件
<script src="https://unpkg.com/react@18/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js" crossorigin></script>
第二种:创建反应应用
npx create-react-app my-app
cd my-app
npm start
接下来的例子将用 引入js文件 方式书写,重要是掌握语法,两种方式都大同小异。
2:开始
创建一个html文件:index.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=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
</div>
<script src="https://unpkg.com/react@18/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js" crossorigin></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
const root = ReactDOM.createRoot(document.getElementById('app'));
root.render(
<h1>Hello, world!</h1>
);
</script>
</body>
</html>
这就是第一个示例。
3:使用 class 和 function 创建组件
3.1:function 组件
推荐函数名 大写:
function HelloWorld(){
return(
<h1>Hello, world!</h1>
)
}
const root = ReactDOM.createRoot(document.getElementById('app'));
root.render(
<HelloWorld />
);
往函数内传值:
function HelloWorld(props){
return(
<h1>Hello, world! {props.name}!</h1>
)
}
const root = ReactDOM.createRoot(document.getElementById('app'));
root.render(
<HelloWorld name="anny"/>
);
3.2:class 组件
class HelloWorld extends React.Component{
constructor(props){
super(props)
}
render(){
return(
<h1>Hello, world! {this.props.name}!</h1>
)
}
}
const root = ReactDOM.createRoot(document.getElementById('app'));
root.render(
<HelloWorld name="anny"/>
);
- 组件类需要继承 React.Component
- 在 render() 函数内返回 组件内容。
4:生命周期
挂载:
1. constructor()
2. static getDerivedStateFromProps()
3. render()
4. componentDidMount()
更新:
1. static getDerivedStateFromProps()
2. shouldComponentUpdate()
3. render()
4. getSnapshotBeforeUpdate()
5. componentDidUpdate()
卸载:
1. componentWillUnmount()
常用:
生命周期 | 函数 |
挂载 | componentDidMount |
更新 | componentDidUpdate |
卸载 | componentWillUnmount |
5:state
class HelloWorld extends React.Component{
constructor(props){
super(props)
this.state = {
name:'tony'
}
}
render(){
return(
<h1>{this.state.name} said Hello, world! {this.props.name}!</h1>
)
}
}
const root = ReactDOM.createRoot(document.getElementById('app'));
root.render(
<HelloWorld name="anny"/>
);
初始值:this.state = {XXX:XXXX}
取值:this.state.XXXX
更改值:this.setState({ XXX:XXX })
创建一个倒计时:
class HelloWorld extends React.Component{
constructor(props){
super(props)
this.state = {
time:100,
sit:null
}
}
componentDidMount(){
this.sit = setInterval(()=>{
this.setState({
time:--this.state.time
})
},1000)
}
componentWillUnmount(){
clearInterval(this.sit);
}
render(){
return(
<h1>{this.state.time}</h1>
)
}
}
const root = ReactDOM.createRoot(document.getElementById('app'));
root.render(
<HelloWorld name="anny"/>
);
6:事件处理
6.1:方式一:不绑定this
class HelloWorld extends React.Component{
constructor(props){
super(props)
this.state = {
time:100,
sit:null
}
}
handle(){
alert('click');
}
render(){
return(
<h1 onClick={this.handle}>click me !</h1>
)
}
}
这种方式不会绑定 this,所以在handle中不可以直接获取 this.state。
6.2:方式二:绑定this,返回函数调用
class HelloWorld extends React.Component{
constructor(props){
super(props)
this.state = {
time:100,
sit:null
}
}
handle(){
alert(this.state.time);
}
render(){
return(
<h1 onClick={()=>{this.handle()}}>click me !</h1>
)
}
}
这种方式会自动绑定this,可以直接获取this.state 属性。
6.3:方式三:绑定this,使用bind绑定
class HelloWorld extends React.Component{
constructor(props){
super(props)
this.handle = this.handle.bind(this);
this.state = {
time:100,
sit:null
}
}
handle(){
alert(this.state.time);
}
render(){
return(
<h1 onClick={this.handle}>click me !</h1>
)
}
}
7:条件渲染
function Login(props){
if(props.isLogin){
return(
<button onClick={props.handleChild}>退出登录</button>
)
}
return(
<button onClick={props.handleChild}>立即登陆</button>
)
}
class HelloWorld extends React.Component{
constructor(props){
super(props)
this.handle = this.handle.bind(this)
this.state = {
isLogin:false
}
}
handle(){
this.setState({
isLogin:!this.state.isLogin
})
}
render(){
return(
<div>
<Login handleChild={this.handle} isLogin={this.state.isLogin}/>
</div>
)
}
}
需要注意的是,应避免直接在子组件中修改props参数值
可以通过抛出事件传递给父组件,让父组件去修改自身的state值
8:列表
关于列表,你可以返回一个包含标签的数组,进而渲染出列表dom。
此外,请不要忘了设置key,否则你将收到一个来自react的警告。
function List(){
let li = [];
let a = [1,2,3,4,5];
for(let i = 0;i<a.length;i++){
li.push(<li key={i}>{a[i]}</li>)
}
return li
}
class HelloWorld extends React.Component{
constructor(props){
super(props)
}
render(){
return(
<ul>
<List />
</ul>
)
}
}
设置key可以提高虚拟dom的diff判断,对提高性能非常有效。
9:受控组件值的实时修改
受控组件包含 input、textarea、select 等
如果学过vue,应该非常熟悉 v-model 语法糖,可以非常方便的获取更改表单的数据。
创建一个 input 组件:
function Input(){
return (
<input type="text" />
)
}
把它放到我们的父组件中:
function Input(){
return (
<input type="text" />
)
}
class HelloWorld extends React.Component{
constructor(props){
super(props)
}
render(){
return(
<div>
<Input />
<Input />
</div>
)
}
}
这时候我们可以看到两个输入框
接下来我们通过修改一个 input 框的值自动更改另一个输入框的值:
function Input(props){
return (
<input value={props.value} onChange={props.childChange} type="text" />
)
}
class HelloWorld extends React.Component{
constructor(props){
super(props)
this.childChange = this.childChange.bind(this);
this.state = {
value1:'',
value2:''
}
}
childChange(e){
this.setState({
value1:e.target.value,
value2:e.target.value
})
}
render(){
return(
<div>
<Input value={this.state.value1} childChange={this.childChange}/>
<Input value={this.state.value2} childChange={this.childChange}/>
</div>
)
}
}
此时,无论修改哪一个输入框,都会自动修改另一个输入框的值。
需要注意的是:前面我们说过,应避免直接在子组件中修改 props 值,尽量使用子组件抛出事件在父组件接收,进而在父组件中修改该值。主要原因是,后期代码多了,会很难查找具体修改这个变量的位置。