React SilverCat 2024-05-27 2024-05-29 React 列表渲染 const sorngs=[ {id : 1 , name :'老八' }, {id : 2 , name :'旱魃走' }, {id : 3 , name :'李东' } ] const list=(<ul > {sorngs.map(item=><li className ="titlle" key ={item.id} > {item.name}</li > )} </ul > )ReactDOM .render (list,document .getElementById ('root' ))
函数组件 函数组件(其一)
使用js中的函数创建的组件叫:函数组件
函数组件必须有返回值
组件名称必须大写字母开头,React据此区分组件和普通Reate 元素
使函数名作为组件的标签名
function Hello ( ){ return ( <div > lido</div > ) } ReactDOM .render (<Hello /> ,document .getElementById ('root' ))
函数组件(其二) 使用类创建组件
类组件:使用 ES6 的 class 创建的组件
约定1:类名称也必须以大写字母开头
约定2:类组件应该继承 React.Component 父类,从而可以使用父类中提供的方法或属性
约定3:类组件必须提供render0方法
约定4:render0方法必须有返回值,表示该组件的结构
class Hello extends React.Component { render ( ) { return ( <div > 第一个</div > ) } } ReactDOM .render (<Hello /> ,document .getElementById ('root' ))
抽离为独立 JS 文件
创建Hello.js
在hello.js中导入反应
创建组件(函数 或 类)4.在hello.js中导出该组件
在index,js中导入Hello组件
渲染组件
先创建一个js文件(Hello.js) import React from "react" ;class Hello extends React.Component { render ( ) { return ( <div > 抽离js文件 </div > ) } } export default Hello
在抽离并且渲染 import Hello from './Hello' ReactDOM .render (<Hello /> ,document .getElementById ('root' ))
React中事件绑定 普通触发事件 const handleCilk =( )=>{ console .log ('button被点击了' ) } return ( <div className ="App" > <button onClick ={handleCilk} > click me</button > </div > );
事件参数e const handleCilk =(e )=>{ console .log ('button被点击了' ,e) } return ( <div className ="App" > <button onClick ={handleCilk} > click me</button > </div > );
传递自定义参数 const handleCilk =(name )=>{ console .log ('button被点击了' ,name) } return ( <div className ="App" > <button onClick ={() => handleCilk('jack')}>click me</button > </div > );
既要传递自定义参数,而且还要事件对象 const handleCilk =(name,e )=>{ console .log ('button被点击了' ,name,e) } return ( <div className ="App" > <button onClick ={(e) => handleCilk('jack',e)}>click me</button > </div >
React定义组件 function Button ( ){ return <button > clik me</button > } function App ( ) { return ( <div className ="App" > {/*2,使用组件(渲染组件)*/} {/*自闭合*/} <Button /> {/*成对标签*/} <Button > </Button > </div > ); }
也可以使用箭头函数 const Button = ( ) => { return <button > clik me</button > } function App ( ) { return ( <div className ="App" > {/*2,使用组件(渲染组件)*/} {/*自闭合*/} <Button /> {/*成对标签*/} <Button > </Button > </div > ); }
useState使用
usestate 是一个 React Hook(函数),它允许我们向组件添加一个状态变量,从而控制影响组件的渲染结果
本质:和普通JS变量不同的是,状态变量一旦发生变化组件的视图UI也会跟着变化(数据驱动视图
做一个计数器 import {useState} from "react" ;function App ( ) { const [conut,setCount] =useState (0 ) const handleClick =( )=>{ setCount (conut+1 ) } return ( <div className ="App" > <button onClick ={handleClick} > {conut}</button > </div > ); }
修改状态的规则 状态不可变
在React中,状态被认为是只读的,我们应该始终替换它而不是修改它,直接修改状态不能引发视图更新
直接修改,无法引发视图更新 let [conut,setCount] =useState (0 ) const handleClick =( )=>{ conut++ console .log (conut) }
引发视图更新 const handleClick =( )=>{ setCount (conut+1 ) }
修改对象状态
规则:对于对象类型的状态变量,应该始终传给set方法一个全新的对象来进行修改
错误写法 const [from ,setForm]=useState ({name :'jack' })const changForm =( )=>{ from .name ='johm' }
正确写法 const [from ,setForm]=useState ({name :'jack' })const changForm =( )=>{ setForm ({ ...from , name :'john' }) }
组件基础样式方案 行内样式(不推荐) <div style={color :'red' }>this is div</div>
外部行内样式(不推荐) const style={ color :'red' , fontSize :'50px' } function App ( ) { return ( <div > <span style ={style} > this is span</span > </div > ); }
Class类名控制
记得导入样式
import './index.css' function App ( ) { return ( <div > <span className ='foo' > this is span</span > </div > ); }
classnames优化类名控制
classnames是一个简单的JS库,可以非常方便的通过条件动态控制class类名的显示
没优化前 {tabs.map (item => <span key ={item.type} onClick ={() => handleTabChange(item.type)} className={`nav-item ${type===item.type && `active`}`}>{item.text} </span > )}
优化后
安装库 npm install classnames
{tabs.map (item => <span key ={item.type} onClick ={() => handleTabChange(item.type)} className={classNames('nav-item',{active:type===item.type})}>{item.text} </span > )}npm install classnames
受控绑定表单 function App ( ) { const [value,setValue]=useState ('' ) return ( <div > <input value ={value} onChange ={(e) => setValue(e.target.value)} type="text"/> </div > ); }
父传子 props说明
props可传递任意的数据,数字,字符串,布尔值,数组,对象,函数,JSX
function Son (props ){ console .log (props) return <div > this is mo||{props.name},{props.child}</div > } function App ( ) { const name='this fk' return ( <div > <Son name ={name} age ={18} isTrue ={false} list ={[ 'vue ','react ']} obj ={{name: 'jack '}} cb ={() => console.log(123)} child={<span > this is span</span > } /> </div > ); }
props是只读对象 子组件只能读取props中的数据,不能直接进行修改,父组件的数据只能由父组件修改
下面是错误写法
function Son (props ){ console .log (props) props.name ='new name' return <div > this is mo||{props.name},{props.child}</div > }
特殊的props children
当我们把内容嵌套在子组件标签中时,父组件会自动在名为children的prop属性中接收该内容
首先给子组件传过一个父组件中的函数,传过来用onGetSonMsg来接收,在用onGetSonMag(sonMsg)调用,调用的同时把里面的数据传过去,msg来进行接收
function Son ({onGetSonMag} ){ const sonMsg='this is on msg' return ( <div > this is SON <button onClick ={() => onGetSonMag(sonMsg)}>sendMsg</button > </div > ) } function App ( ) { const [msg,setMsg]=useState ('' ) const getMsg =(msg )=>{ console .log (msg) setMsg (msg) } return ( <div > this is App,{msg} <Son onGetSonMag ={getMsg}/ > </div > ); }
使用状态提升实现兄弟组件通信 子传父,父传子
借助“状态提升”机制,通过父组件进行兄弟组件之间的数据传递
1.A组件先通过子传父的方式把数据传给父组件App
2.App拿到数据后通过父传子的方式再传递给B组件
这里可能有点绕,让我们来整理一下,我们要先从A的值传入App中实现子传父,app算是个类似中转站的东西,然后吧APP里面的name的值传入B中,实现父传子
function A ({onGetAName} ){ const name='this is A name' return ( <div > this is A compnent, <button onClick ={() => onGetAName(name)}>send</button > </div > ) } function B ({name} ){ return ( <div > this is B compnent, {name} </div > ) } function App ( ) { const [name,setName]=useState () const getAname =(name )=>{ console .log (name) setName (name) } return ( <div > this is compnent, <A onGetAName ={getAname}/ > <B name ={name}/ > </div > ); }
使用Context机制跨层级组件通信 实现步骤: 1.使用createContext方法创建一个上下文对象Ctx
2.在顶层组件(App)中通过 Ctx.Provider 组件提供数据
3.在底层组件(B)中通过 usecontext 钩子函数获取消费数据
const MsgContext =createContext ()function A ( ){ return ( <div > this is A component <B /> </div > ) } function B ( ){ const msg= useContext (MsgContext ) return ( <div > this is B compnent,{msg} </div > ) } function App ( ) { const msg='this is app msg' return ( <div > <MsgContext.Provider value ={msg} > this is app <A /> </MsgContext.Provider > </div > ); }