React learning
day1
JSX
{/* 使用引号传递字符 */}
{'this is an App '}
{/* 使用js变量 */}
{count}
{/* 函数调用和方法调用 */}
{getName()}
{new Date().getDate()}
{/* 使用js对象 */}
<div style={{color:'red'}}>hihihi</div>
注意:if语句 switch语句 变量声明属于语句 不是表达式 不能出现在{}中
实现渲染列表
const list = [
{ id:1001, name:'wcn'},
{ id:1002, name:'jcc'},
{ id:1003, name:'ys'},
]
function App() {
return (
<div className="App" >
this is an App
{/* 列表渲染 */}
{/* map循环哪个结构 return结构 */}
{/* 注意事项: 加上一个独一无二的key 字符串或者number */}
{/* 作用react内部使用提高更新性能*/}
<ul>
{list.map(item => <li key={item.id}>{item.name}</li>)}
</ul>
</div>
);
}
实现渲染条件
const isLogin = true;
function App() {
return (
<div className="App" >
{/* 逻辑与 && */}
{isLogin && <span>this is span</span>}
{/* 三元运算 */}
{isLogin ? <span>Jack</span> : false}
</div>
);
}
export default App;
实现复杂渲染条件
const nameType = 3; // 0 1 3
const getName = ()=>{
if (nameType === 0){
return <div>没名字</div>
}else if (nameType === 1){
return <div>我有一个名字</div>
}else if (nameType === 3){
return <div>我有好多名字</div>
}
}
function App() {
return (
<div className="App" >
{getName()}
</div>
);
}
export default App;
事件绑定
//基础绑定
// const handleClick = ()=>{
// console.log('button 被点击了')
// }
//事件参数e
// const handleClick = (e)=>{
// console.log('button 被点击了',e)
// }
//传递字段定义参数
//const handleClick = (name)=>{
// console.log('button 被点击了',name)
// }
//同时传递事件对象和自定义参数
const handleClick = (name,e)=>{
console.log('button 被点击了',name,e)
}
function App() {
return (
<div className="App" >
<button onClick={(e)=>handleClick('jack',e)}>button</button>
</div>
);
}
export default App;
React组件
const Button = ()=>{
return <button> click me! </button>
}
function App() {
return (
<div className="App" >
{/* 自闭和 */}
<Button/>
{/* 成对标签 */}
<Button></Button>
</div>
);
}
export default App;
useState基础使用
useState是一个 React Hook(函数), 它允许我们向一个组件添加一个状态变量,从而控制影响组件的渲染效果
- useState是一个函数,返回值是一个数组
- 数组中的的第一个参数是状态变量,第二个参数是set函数用来修改状态变量
- useState的参数将作为count的初始值
import {useState} from "react";
function App() {
const [count,setCount] = useState(0)
const handleClick = ()=>{
setCount(count + 1)
}
return (
<div className="App" >
<button onClick={handleClick}>{count}</button>
</div>
);
}
export default App;
修改状态规则
import {useState} from "react";
function App() {
const [count, setCount] = useState(0)
const handleClick = () => {
setCount(count+1)
}
const [form, setForm] = useState({name: 'Jack'})
const changeForm = () => {
setForm({
...form,
name: 'John',
})
}
return (
<div className="App">
<button onClick={handleClick}>click me {count}</button>
<button onClick={changeForm}>修改form{form.name}</button>
</div>
);
}
export default App;
组件基础样式方案
import "./index.css"
const style = {
color: 'red', fontSize: '100px'
}
function App() {
return (
<div>
{/* 通过行内样式控制 */}
<span style={style}>div</span>
{/* 通过类名class控制 */}
<span className="foo">this is foo</span>
</div>
);
}
export default App;
.foo{
color: yellow;
font-size: 100px;
}
day2
受控表单绑定
import {useState} from "react";
function App() {
const [value,setValue] = useState('')
return (
<div>
<input
value={value}
onChange={(e)=> setValue(e.target.value)}
type={"text"}
>
</input>
</div>
);
}
export default App;
React中获取dom
import {useRef, useState} from "react";
// 1. useRef生成ref对象 绑定到dom标签身上
// 2. dom可用时, ref.current获取dom
// 渲染完毕之后dom生成之后才可用
function App() {
const inputRef = useRef(null)
const showDom = () =>{
console.dir(inputRef.current)
}
return (
<div>
<input
type={"text"}
ref={inputRef}
></input>
<button onClick={showDom}>获取DOM</button>
</div>
);
}
export default App;
父传子基础实现
//父传子
//1.父组件传递数据 子组件标签身上绑定属性
//2.子组件接收数据 props的参数
function Son(props) {
//props:对象里面包含了父组件传递过来的所有数据
console.log(props)
return <div> this is son {props.content} </div>
}
function App() {
const name = 'this is father'
return (
<div>
<Son content={name}/>
</div>
);
}
export default App;
说明
-
props可以传递任意的数据
数字、字符串、布尔值、数组、对象、函数、JSX
<Son content={name} age={20} isTrue={false} list={['Vue','React']} obj={{name:'jack'}} cb={()=>console.log(123)} child={<span>this is a span child</span>} /> -
props是只读对象
子组件只能读取props中的数据,不能直接进行修改,父组件的数据只能由父组件修改
特殊的props children
function Son(props) {
//props:对象里面包含了父组件传递过来的所有数据
console.log(props)
return <div>this is son {props.children}</div>
}
function App() {
return (
<div>
<Son>
<span>this is span</span>
</Son>
</div>
);
}
export default App;
子传父
import {useState} from "react";
function Son({onGetSonMsg}) {
const sonMsg = "this is son msg"
return <div>
this is son
<button onClick={()=> onGetSonMsg(sonMsg)}>sendMsg</button>
</div>
}
function App() {
const [msg,setMsg] = useState('')
const getMsg = (msg) => {
setMsg(msg)
}
return (
<div>
this is app {msg}
<Son onGetSonMsg={getMsg}>
</Son>
</div>
);
}
export default App;
使用状态提升实现兄弟组件通信
先把子组件A的内容给父组件app(子传父),再把父组件app获取的A的内容传给子组件B(父传子)
import {useState} from "react";
function A({onGetAName}) {
const name = "this is son msg"
return <div>
this is A
<button onClick={()=> onGetAName(name)} >sendMsg</button>
</div>
}
function B({name}) {
return <div>
this is B {name}
</div>
}
function App() {
const [AName,setAName] = useState()
const getAName = (name) =>{
console.log(name)
setAName(name)
}
return (
<div>
this is app {AName}
<A onGetAName={getAName}/>
<B name={AName}/>
</div>
);
}
export default App;
使用context机制跨层组件通信
实现步骤
- 使用createContext方法创建一个上下文对象Ctx
- 在顶层组件(App)中通过Ctx.Provider组件提供数据
- 在底层组件(B)中通过useContext钩子函数获取消费数据
import {createContext, useContext} from "react";
const msgContext = createContext(undefined)
function A() {
return <div>
this is a
<B/>
</div>
}
function B() {
const msg = useContext(msgContext)
return <div>
this is B {msg+'111'}
</div>
}
function App() {
const msg = 'this is app msg'
return (
<div>
<msgContext.Provider value={msg}>
this is app
<A />
</msgContext.Provider>
</div>
);
}
export default App;
useEffect的使用
相当于vue的生命周期函数(mounted、onmounted 等等)
useEffect是一个React Hook函数,用于在React组件中创建不是由事件引起而是由渲染本身引起的操作,AJAX请求,更改DOM等等
说明:上面的组件中没有发生任何的用户事件,组件渲染完毕之后就需要和服务器要数据,整个过程属于"只由渲染引起的操作"
useEffect依赖项参数说明(即[])
没有依赖项(无论什么变化都执行)
function App() {
const [count,setCount] = useState(0)
useEffect(() => {
console.log('副作用执行!!')
})
return (
<div>
<button onClick={()=>setCount(count+1)}>{count}</button>
</div>
);
}
空数依赖项(只有第一次渲染的时候执行)
function App() {
const [count,setCount] = useState(0)
useEffect(() => {
console.log('副作用执行!!')
},[])
return (
<div>
<button onClick={()=>setCount(count+1)}>{count}</button>
</div>
);
}
添加特定依赖项(案例只要有count发生变化才执行)
function App() {
const [count,setCount] = useState(0)
useEffect(() => {
console.log('副作用执行!!')
},[count])
return (
<div>
<button onClick={()=>setCount(count+1)}>{count}</button>
</div>
);
}
清除副作用
最常见的清楚时期是在组件卸载时自动执行
import {useEffect, useState} from "react";
function Son(){
useEffect(() => {
const timer = setInterval(()=>{
console.log('定时器执行中...')
},1000)
return ()=>{
clearInterval(timer)
}
}, []);
return(
<div>
this is son
</div>
)
}
function App() {
const [show,setShow] = useState(true)
return (
<div>
{show && <Son/>}
<button onClick={()=>setShow(false)}>卸载Son组件</button>
</div>
);
}
export default App;
自定义Hook函数
当组件耦合在一起不方便复用时
- 声明一个use开头的函数
- 在函数体内封装可复用的逻辑
- 把组件中用到的状态或者回调return出去
- 在哪个组件中要用到这个逻辑,就执行这个函数,结构出来的状态和回调进行使用
function useToggle() {
const [value, setValue] = useState(true)
const toggle = () => setValue(!value)
return {
value,toggle
}
}
function App() {
const {value,toggle} = useToggle();
return (
<div>
{value && <div>this is div</div>}
<button onClick={toggle}>toggle</button>
</div>
);
}
使用规则
- 只能在组件中或者其他自定义Hook函数中调用
- 只能在组件的顶层调用,不能嵌套在if、for和其他函数中