一、React项目的入口文件
React项目的入口文件(
create-react-app
):index.js
1、React.StrictMode:检测工具,检查React项目是否存在潜在风险、不会渲染任何真实的DOM。可以用在任何地方
(1)识别不具备生命周期的组件
(2)检查旧时字符串的用法
(3)检查弃用的方法
二、React的组件
1、什么是组件
组件:是视图的抽象
2、组件的分类
(1)函数组件:推荐使用
(2)类组件:必须继承自React.Component
类,并且必须有render
方法,在render方法中用return语句来定义要渲染的视图。
a、组件文件的扩展名可以是.js,也可以是.jsx
b、<Fragment></Fragment>
等价于<></>
c、在return中必须要有一个根标签
3、组件间的通信
组件间的通信:是单向数据流设计,即数据只能从父级向子级一层一层的向下传递
(1)父级向子级通信
在父组件中调用子组件时,只需要将想要传递的数据加在子组件的属性上, 然后子组件内部通过props属性来接收
💥举例:
index.js(自定义文件夹data下的子文件,并不是上文的入口文件index.js)代码段
let data = {
family:{
title:'家人',
list:[
{ name:'爸爸'},
{ name:'妈妈'}
]
},
friend:{
title: '朋友',
list:[
{ name:'郭靖'},
{ name:'黄蓉'},
{ name:'老顽童'}
]
},
customer:{
title:'客户',
list:[
{ name:'阿里'},
{ name:'腾讯'},
{ name:'小米'}
]
}
}
export default data;
App.js父组件代码段
import data from "./data";
function App() {
return (
<div className="App">
{
Object.keys(data).map((itemName) => {
return <First key={itemName} dlData={data[itemName]}/>
})
}
</div>
);
}
export default App;
First.jsx(子组件)代码段:
import React,{Component} from "react";
//如果没有导入Component,则需要写成 class First extends React.Component
class First extends Component{
render() {
let { dlData } = this.props
return (
<>
<dl className='first-group'>
<dt>{dlData.title}</dt>
{
dlData.list.map((item,index)=>{
return <dd key={index}>{item.name}</dd>
})
}
</dl>
</>
)
}
}
export default First;
(2)子组件向父组件传递数据
子组件向父组件传递数据:React是单向数据流,无法从子组件直接将数据传递给父组件。可以在父组件中定义好回调函数,把回调函数传递给子组件,利用回调函数向父组件传递数据
Father.jsx代码段
import React,{Component} from "react";
import Son from "./Son";
class Father extends Component{
constructor(props) {
super(props);
}
showInfo(name){ //回调函数
console.log('子组件的Name:'+name)
}
render() {
return (
<Son openShow={this.showInfo}/> //将回调函数传递给子组件
)
}
}
export default Father;
Son.jsx代码段
import React,{Component} from "react";
class Son extends Component{
constructor(props) {
super(props);
}
render() {
let { openShow } = this.props
return(
<button onClick={()=>{
openShow('刘备')
}}>我是子组件</button>
)
}
}
export default Son;
App.js代码段
import Father from "./components/Father";
function App() {
return (
<div className="App">
<Father/>
</div>
);
}
export default App;
(3)同级组件之间的传递
React是单向数据流,同级组件之间无法直接传递数据。可以通过父组件来完成同级之间的数据传递
注意:组件的状态state的使用
- 在React中,组件就是一种状态机,组件会根据状态的不同输出不同的UI。需要交互时,只需要把交互和状态关联起来
- 定义state:state是组件实例的一个属性,它的值是一个对象,在类组件的构造方法中定义。
this.state = {}
- 更新state:调用
setState
方法。因为视图和state是绑定的,所以当state更新后,视图也会重新渲染。
过程:调用setState方法后,会根据setState传入的值,对state进行修改,state生成新的虚拟的DOM,将新的虚拟的DOM和老的虚拟的DOM进行对比,
找到修改点对视图进行更新。
注意:组件中的函数绑定this的方法:组件中的普通函数是没有绑定this的
- 使用
bind()
函数绑定this:在构造函数中定义以下语句this.函数名 = this.函数名.bind(this)
- 使用箭头函数
💥举例:
Counter.jsx代码段:
import React,{Component} from "react";
import Counter1 from "./Counter1";
import Counter2 from "./Counter2";
class Counter extends Component{
constructor(props) {
super(props);
this.state = { //组件的状态属性
name:'西邮',
age:'70',
counter1Name:''
}
this.changeName=this.changeName.bind(this) //绑定this
}
changeName(sonName){ //没有使用箭头函数:找到this
this.setState({
counter1Name: sonName
})
}
//普通函数没有this,改为使用箭头函数:找到this
/* changeName=(sonName)=>{
this.setState({
counter1Name:sonName
})
}*/
render() {
let{name,age}=this.state //解构
return (
<>
<p>姓名:{ name}</p>
<p>年龄:{age}</p>
<button onClick={()=>{
this.setState({
age: ++age
})
}}>过了一年</button>
<br/><br/>
<Counter1 modifyName={this.changeName} />
<Counter2 counter1Name={this.state.counter1Name} />
</>
);
}
}
export default Counter;
Counter1.jsx代码段:
import React,{Component} from "react";
export default class Counter1 extends Component{
constructor(props) {
super(props);
this.state = {
name:'张良'
}
}
render() {
let { modifyName} = this.props
return (
<div className='div1'>
<button onClick={()=>{
modifyName(this.state.name)
}
}>我是Counter1</button>
<br/><br/>
<p>姓名:{this.state.name}</p>
</div>
)
}
}
Counter2.jsx代码段:
import React,{Component} from "react";
class Counter2 extends Component{
render() {
let {counter1Name}=this.props
return (
<div className='div2'>
<button>我是Counter2</button>
<br/><br/>
<p>
来自Counter1的Name:{ counter1Name }
</p>
</div>
)
}
}
export default Counter2;
App.js代码段:
import './App.css';
import Counter from "./components/Counter";
function App() {
return (
<div className="App">
<Counter/>
</div>
);
}
export default App;
index.css代码段:
.div1{
width: 100px;
height: 100px;
background-color: red;
margin: 100px auto;
}
.div2{
width: 250px;
height: 150px;
color: #eeeeee;
background-color: blue;
margin: 100px auto;
}