一. jsx语法
1. 定义虚拟dom时不要用引号
2. 标签中引入js表达式要用{} {}里面的语法会被当作js语法编译 所以:
如果在jsx要写行内样式需要使用style={{coler:red}}形式;
样式的类名指定不能写class,要写className
3. 只有一个根标签
4. 标签必须闭合
5.标签首字母:
①若小写字母开头,则会将该标签转为html同名标签,如果没找到,则会报错;.
② 若大写字母开头,则会认为是组件,它就会去找对应的组件,如果没找到,就会报组件未定义的错误;
二.组件实例对象的三大属性
1. state 状态
state状态只能组件内部使用 所以封装的子组件要改变父组件的state 就要用props属性来通知父组件来改变
子组件要少写状态 因为有状态 组件就会不受控 无疑带来了管理的复杂性 相比之下 无状态组件会降低代码维护的难度 也在一定程度上增强了组件的复用性
- state是组件实例对象最重要的属性,必须是对象的形式
- 组件被称为状态机,通过更改state的值来达到更新页面显示(重新渲染组件 render)
- 组件render中的this指的是组件实例对象
- 状态数据不能直接赋值,需要用setState()
- 组件自定义方法中的this为undefined,怎么解决?:
- ①将自定义函数改为表达式+箭头函数的形式(推荐)
- ②在构造器中用bind()强制绑定this
2. props 属性
props就是在调用组件的时候在组件中添加属性传到组件内部去使用
- 父传子 直接用属性
父组件
子组件
- 子传父 要用一个回调函数
就是子组件通知父组件 然后父组件做相应的操作
今天在来补充一下 在父组件里面定义一个方法 然后把这个方法当成一个参数传给子组件 再加俩图
子组件
父组件
event随便起名字 都可以
父组件
子组件
函数式组件 内部不维护什么状态 通过props属性访问 回调函数调用触发在父组件身上的状态 从而再次传回来
如果要对传入的props属性进行一些必传、默认值、类型的校验,可以下载一个prop-types库
下载:npm i prop-types --save
引入:import PropTypes from ‘prop-types’
- 每个组件都会有props属性
- 组件标签的所有属性都保存在props
- 组件内部不能改变外部传进来的props属性值
3. refs属性
组件内的标签可以定义ref属性来标识自己
1. 字符串形式的ref <input ref="input1"/> (废弃)
2. 回调形式的 ref <input ref= { (c) = > {this.input1 = c }} />
3. creatRef创建 ref容器 myRef = React.reactRef() <input ref={this.myRef}/>
这样就可以打印出用户输入到input里面的值
三. React中的事件处理
- 通过onXxxx属性指定事件处理函数(小驼峰形式)
- 通过event.target可以得到发生事件的Dom元素
- 使用 JSX 语法时你需要传入一个函数作为事件处理函数,而不是一个字符串。
四.生命周期(类组件 常用的3个)
- 挂载时 componentDidMount. 开启监听, 发送ajax请求
- 更新时 componentDidUpdate 由组件内部this.setSate()或父组件重新render触发
- 卸载时 componentWillUnmount 做一些收尾工作, 如: 清理定时器
render:初始化渲染或更新渲染调用 (render函数 内部状态改变或里边组件props值改变的时候会重新渲染)
Fragment标签
<Fragment><Fagment> <></> 可以不必有一个真实dom根标签 类似于vue2的根标签
五.react插槽
子组件:
父组件:
如果子组件没写slot插槽 父组件里引入的swiper组件里面的div里的内容是无法显示的
作用:1.为了复用 (主要作用)
2.一定程度上减少父子通信(但是代替不了通信)
封装好的组件 (如图中Swiper) 写在哪个组件里边(如图中父组件) 就可以访问到哪个组件的状态
六. hooks(函数组件)
Hook 是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性。我这里写的比较初级 详细可看官网 : Hook API 索引 – React
hook里面没有this 不用this. 来取值
1. useState(保存组件状态)
const [state , setState] = useState(initialState)
state 和setState 是解构赋值 所以是两个灵活的值 可以自己取名字
- 返回一个state, 以及更新state的函数
- initialState是一个初始值 (state的初始值)
- setState函数用于更改state的值 并引起页面的重新渲染
- 在后续的重新渲染中,
useState
返回的第一个值将始终是更新后最新的 state。就是state始终是最新的值。
2.useEffect(处理副作用)
一个项目中支持写多个useEffet 里面可以写一些请求数据的操作
数组为空的时候 useEffet中的回调函数只会执行一次 避免了重复调用 如果数组里传的有依赖 那么只有依赖发生改变才会重新执行
useEffect (() => {
effet
return () => {
cleanup
}
},[依赖的状态;空数组表示不依赖])
useEffet里面传两个参数 第一个是回调函数 第二个是数组
如图中name 用到这个依赖 若数组里不传 后果就是 当name(依赖)更新时 useEffet也不会再执行
3. useContext (减少组件层级)
const value = useContext(MyContext);
4.自定义hook
我目前的理解是 自定义hook其实是把js逻辑抽出来封装成一个单独的函数 把逻辑抽出来让结构看起来更清晰 hooks就是复用的逻辑
5. useMemo (记忆组件)
类似于vue的计算属性 作为性能优化的手段
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
把“创建”函数和依赖项数组作为参数传入useMemo
它仅会在某个依赖项改变时才重新计算 memoized 值
6.useNavigate(路由跳转)
query传参
路由传参 navigate( `/ detail / ${ id } ` ) 路由入口文件配置 path="/detail / :id"
这块写的不是很清晰 后边再补充
七. 关于react请求数据
我主要用hooks 所以写hooks 其实就是useState()和useEffect()结合使用 见图:
- 直接在 useEffect 里使用 async 函数是不允许的。 安照标准 async函数会返回一个隐式的promise。但是,effect hook不能返回任何任何东西,也不能返回函数。 所以需要声明一个变量接受一下async函数 再放进effect hook。
- 然后useState()中的state 我理解为vue中的data 可以用setState把后台数据存到state。后面页面用的时候就是{state.name} 或者是 useState( { list : [ ] } ) 数据是数组 我就简写一下state.list.map(item=>{ <div> { item . name} <div>}
- 也可以自己在store中写一些方法 不过尽量类组件再这样用
待续