# 组件
## 概念
> 由虚拟dom带有一定功能并且可复用的效果,就是组件
## 特点
- 1.低耦合
- 2.可复用
## 分类
### 语法
- 函数组件
- 类组件
### 功能
- 受控组件
- 非受控组件
### 效果
- ui组件
- 页面组件
## 三大属性
### state
> 表示组件内部私有的状态,为响应式数据,作用:用于控制组件内部的交互
**注意:类组件和函数组件中state的创建/修改/读取方式是不一样的**
#### 函数组件中state
- 1.函数名大驼峰
- 2.在使用组件/组件重新渲染 时函数重新执行
~~~ js
//1.结构赋值
//2.声明两个变量
//3.给两个变量赋值
/*React.useState()
作用:创建响应式状态
参数:js任意类型数据
返回值:数组[0] 响应式状态值, 数组[1]是函数作用修改响应式状态 数组[0] 的赋值
注意:只能在函数组件内部使用
let arr =React.useState(true);
let val =arr[0];
let setVal=arr[1];
arr[1](false) //意思是将数组arr中第二个参数:arr[1]的 修改为 false
*/
// let [val, setVal] = React.useState(true);
let [flag,setFlag] = React.useState(true); //setFlag 是用来修改 flag的值 (flag是值,setFlag是函数 )
~~~
#### 类组件中state
### prop
> 表示接收组件外部传入的实参,作用:定义api 接收父组件传递的参数
**父传子使用基本步骤:**
- 1.使用组件时,定义自定义属性,并赋值状态(为父组件中私有状态)
- 2.在组件内部,通过形参props获取自定义属性和值
~~~ js
<div id="app"></div>
<script src="../0assets/新版本/react.dev.18.2.js"></script>
<script src="../0assets/新版本/react-dom-dev.js"></script>
<script src="../0assets/新版本/prop-type.js"></script>
<script src="../0assets/新版本/babel.min.js"></script>
<script type="text/babel">
const App = () => {
let [msg,setMsg] =React.useState('app私有状态:Helloween ')
setTimeout(()=>{
setMsg('更新了msg')
},2000)
return (
<div>
<Child msg={msg}/>
</div>
)
}
// {msg} 解析赋值 如果不解析则是 props来接收
//1.函数组件中的形参 是 props
// 作用:接收使用组件时,自定义属性和值
const Child=({msg})=>{
//1.传递的state,在子组件中也是响应式状态
return (
<h1>{msg}</h1>
)
}
ReactDOM.render(<App />, document.getElementById('app'))
</script>
~~~
**子传父使用基本步骤**
- 1.父组件:使用组件时,定义自定义属性,并赋值定义的函数
- 2.子组件:在组件中通过 props(可以使用{} 解析 ) 获取自定义属性
- 3.子组件:在组件内部,满足条件时,触发函数,并传入实参(实参为当前组件私有状态)
- 4.父组件:定义函数形参中接受实参
- 5.父组件:如果需要绑定页面上,重新创建一个状态,并在函数中使用setXXX更新状态值
(先父传子一个函数 然后子传父在传入实参,父组件在使用)
~~~js
<body>
<div id="app"></div>
<script src="../0assets/新版本/react.dev.18.2.js"></script>
<script src="../0assets/新版本/react-dom-dev.js"></script>
<script src="../0assets/新版本/prop-type.js"></script>
<script src="../0assets/新版本/babel.min.js"></script>
<script type="text/babel">
const App = () => {
let [msg, setMsg] = React.useState('app私有状态:Helloween ')
let [text,setText] =React.useState('') //7.重新创建一个状态
setTimeout(() => {
setMsg('更新了msg')
}, 2000)
//2.创建函数
const handle = (text) => {
console.log('handle run',text);
setText(text)//8.将子组件中的内容 传入到父组件响应式数据中 (可以在父组件使用了)
}
return (
<div>
<Child msg={msg} onhandle={handle} />
{/* 1.定义自定义属性 onhandle={} 3.传值 onhandle={handle} */}
</div>
)
}
//4.传入 onhandle
const Child = ({ msg,onhandle }) => {
let [text, setText] = React.useState('CHILD 中 sttate')
const sendText=()=>{
onhandle(text) //5.引用onhandle 将实参text 传出到 第二步的形参中
}
return (
<div>
<h1>{msg}</h1>
<button onClick={()=>{sendText()}}>点击传递</button> {/*6.点击传参*/}
</div>
)
}
ReactDOM.render(<App />, document.getElementById('app'))
</script>
~~~
### ref
>
可以解决react 16 转换18 版本的报错问题
16.版本
ReactDOM.render(<App />, document.getElementById('app'))
18. 版本
let root = ReactDOM.createRoot(document.getElementById('app'));
root.render(<App />)