大家好,这是我第一篇文章分享,也是一次近期的自我总结,请多多指教。
基本使用
类组件:
1、类组件配合使用 render 函数返回出需要渲染的 DOM 元素
2、类子组件能直接通过this调用父组件传递的参数
3、为 props 提供默认值,通过静态属性 defaultProps
class List extends Component {
static defaultProps = {
pageSize: 10
}
render() {
return (
<div>
此处展示props的默认值:{this.props.pageSize}
</div>
)
}
}
<List />
4、有生命周期
函数数组件(重点):
1、函数组件通过 return 直接返回需要渲染的 DOM 元素
2、函数自组件需要通过 函数形参来获取
3、没有生命周期
4、为绑定组件传入自定义参数
function App() {
function handleClick(name, e) {
...
}
return (
<div className="App">
<button onClick="{e => handleClick('Jack',e)}">click me</button>
</div>
)
}
5、父传子 为 props 提供默认值,使用参数控制
// 子组件使用
function List(props) {
const {pageSize} = props
return (
<div>
此处展示props的默认值:{ pageSize }
</div>
)
}
// 父组件中使用
<List pageSize={pageSize}/>
6、子传父 在子组件中调用父组件的函数,并传递实参
// 父组件
function App() {
const [msg, setMsg] = useState('')
const getMsg = (msg) => {
setMsg(msg)
}
return (
<div>
this is app, {msg}
<Son onGetSonMsg={getMsg} />
</div>
)
}
// 子组件
function SOn({onGetSonMsg}) {
const sonMsg = 'this is son msg'
return (
<div>
this is son
<button onClick={() => onGetSonMsg(sonMsg)} > sendMsg </button>
</div>
)
}
组件之间传参:
1、父传子: props
2、子传父: 父将接收数据的回调函数传递给子,子将数据作为参数,在调用该回调时进行传递
3、兄弟之间的通信:将通信数据在父组件中进行共享,通过 props 和回调函数实现数据共享
4、跨组件通信:使用context 导出 provider 和 consumer
对父组件传递 props 进行校验:
使用 prop-types 实现对 props 的校验,
校验类型:array、bool、func、number、object、string
必填属性:isRequired
requiredFunc: PropTypes.func.isRequired,
动态添加 style 或 className
// style
<div style={{display: (index===this.state.currentIndex) ? "block" : "none"}}>此标签是否隐藏</div>
<div style={{display: (index===this.state.currentIndex) ? "block" : "none", color:"red"}}>此标签是否隐藏</div>
// className
<div className={index===this.state.currentIndex?"active":null}>此标签是否选中</div>
<div className={["container tab", index===this.state.currentIndex?"active":null].join(' ')}>此标签是否选中</div>
// ES6 推荐
<div className={`container tab ${index===this.state.currentIndex?"active":null}`}>此标签是否选中</div>
react 的基本编写语法:
{ js 代码 }
( jsx 代码 内部只能还有一个根组件)
注意:reander 函数内部不能直接使用 setState 函数 会导致(渲染修改,但渲染过程中又会涉及到修改,会陷入死循环)
react 标签的 style 属性为什么要使用 {{}} 包裹?
style={{borderRadius: '10px'}} 与以下代码同义
const imgCSS = {
borderRadius: '10px'
}
style={imgCSS}
函数组件内部执行 状态修改的函数(副作用函数)
若不是用 useEffect 会导致不断交替执行渲染个修改操作,陷入死循环
useEffect 接收两个函数:(注意 useEffect 会初次默认执行一遍)
1、是一个函数,需要执行的函数
2、是一个数组,函数在什么时候执行第一个函数 af-magic
常用 Hook 函数
useState
useState 是一个 React Hook,允许创建一个状态变量,实现数据驱动视图
// useState 参数可作为状态变量的初始值
// useState 返回一个数组,第一个是状态变量 第二个是 set 函数用来改变状态变量
// 触发 set 函数可以实现 UI 渲染
// React 中状态变量只可被替换,不可被修改 直接修改状态变量触发视图更新 故 count ++ 不会触发视图更新
const [count, setCount] = useState(0)
const [form, setForm] = useState({name: 'jack'})
setForm({
...form,
name: 'jack'
})
useState 高阶使用:使用回调函数计算出初始化参数,只在初始渲染时调用
const [name, setName] = useState(()=>{
// 编写计算逻辑
return '计算之后的初始值'
})
useRef
useRef 可以获取指定的 DOM 元素(函数组件没有实例)
<input ref={inputRef} />
const inputRef = useRef(null)
/* 执行 useRef 函数并传入null,返回值为一个对象 内部有一个current属性存放拿到的dom对象(组件实例) */
/* 获取当前元素 并聚焦 */
inputRef.current.focus()
useEffect
useEffect 控制依赖项副作用的执行时机(类似于监听依赖项的变化)
// 1、不添加依赖项:组件初次渲染执行一次;组件状态更新执行
useEffect(()=>{
console.log('副作用执行了')
})
// 2、空数组:只在首次渲染时执行
useEffect(()=>{
console.log('副作用执行了')
},[])
// 3、添加特定状态值,依赖项变化时执行
const [count, setCount] = useState(0)
useEffect(()=>{
console.log('副作用执行了')
}, [count])
注意事项
useEffect 回调函数中用到的数据(比如,count)就是依赖数据,就应该出现在依赖项数组中,如果不添加依赖项就会有bug出现
清楚 useEffect 的副作用:为副作用函数添加 return
// 执行时机:组件卸载时自动执行;组件更新时,useEffect 函数执行之前
useEffect(() => {
const timerId = setInterval(() => {
setCount(count + 1)
}, 1000)
return () => {
// 用来清理副作用的事情
clearInterval(timerId)
}
}, [count])
useEffect 的高阶使用—发送网络请求
【注意:不可以直接在useEffect的回调函数外层直接包裹 await ,因为异步会导致清理函数无法立即返回】
useEffect(()=>{
async function fetchData(){
const res = await axios.get('http://geek.itheima.net/v1_0/channels') console.log(res)
}
},[])
useContext
- 在顶层组件通过
Provider提供数据 - 在底层组件通过
useContext函数获取数据