一、组件的props
- props的作用:接收传递给组件的数据
- 传递数据,给组件标签添加属性
class App extends React.Component {
state = {
userName: 'yusongH'
}
render() {
return (
<div>
<ComComponent txt="你好啊" userName={this.state.userName}></ComComponent>
</div>
)
}
}
复制代码
- 接收数据
- 函数组件通过
参数props
接收数据
function ComComponent(props) { return ( <div> <div>txt:{props.txt}</div> <div>userName:{props.userName}</div> </div> ) } 复制代码
- 类组件通过
this.porps
接收数据
class ComComponent extends React.Component { render() { return ( <div> <div>txt:{this.props.txt}</div> <div>userName:{this.props.userName}</div> </div> ) } } 复制代码
- 函数组件通过
- 总结
- 可以给组件传递任意类型的数据
- props是
只读
的对象,只能读取属性的值,修改会报错 - 注意点:使用类组件时,如果写了构造函数,应该将props传递给super(),不然无法在构造函数中获取到props
constructor(props) { super(props) console.log(this.props) console.log(props) } 复制代码
三、组件通讯的三种方式
-
父组件 -> 子组件
- 给子组件标签添加属性,值为state中的数据
class App extends React.Component { render() { return ( <div> <ComComponent txt="你好啊" userName={this.state.userName}></ComComponent> </div> ) } } 复制代码
- 子组件中通过props接收父组件中传递的数据
class ComComponent extends React.Component { render() { return ( <div> <div>txt:{this.props.txt}</div> <div>userName:{this.props.userName}</div> </div> ) } } 复制代码
-
子组件 -> 父组件
- 思路:利用回到函数,父组件提供回调,子组件调用回调函数,将需要传递的数据作为回调函数的参数传递过去
- 注意:获取参数的的回调的this指向问题
// 父组件 class ParentComponent extends React.Component { state = { childMsg: '' } // 接收传值回调函数 getChildMsg = (data) => { console.log('父组件传递的参数:', data) // 注意this的指向,所以要使用箭头函数 console.log(this) this.setState({ childMsg: data }) } render() { return ( <div> <div>父组件</div> <div>子组件传递的数据:{this.state.childMsg}</div> <ChildComponent getMsg={this.getChildMsg}></ChildComponent> </div> ) } } // 子组件 class ChildComponent extends React.Component { state = { msg: '给父组件的数据data' } handleClick = () => { // 调用父组件提供的回调 this.props.getMsg(this.state.msg) } render() { return ( <div> <div>子组件</div> <button onClick={this.handleClick}>点击传递数据给父组件</button> </div> ) } } 复制代码
-
兄弟组件
- 状态提升:将共享状态提升到最近的公共父组件中,由公共父组件管理这个状态
- 公共父组件:1、提供共享的状态 2、提供操作这些共享的状态的方法
- 要通讯的子组件只需要通过props接收状态或者操作状态的方法
class BrotherComponent extends React.Component { state = { count: 0 } // 提供给子组件修改状态 changeCount = () => { // 修改状态 this.setState({ count: this.state.count + 1 }) } render() { return ( <div> <FirstChildComponent count={this.state.count} /> <SecondChildComponent changeCount={this.changeCount} /> </div> ) } } class FirstChildComponent extends React.Component { render() { return ( <div>计数器:{this.props.count}</div> ) } } class SecondChildComponent extends React.Component { handleClick = () => { this.props.changeCount() } render() { return ( <button onClick={this.handleClick}>+1</button> ) } } 复制代码
四、Context基本使用
作用:跨组件传值
使用步骤
- 调用React.createContext()创建Provider(提供数据)和Consumer(消费数据)两个组件
// 创建context,Provider,Consumer
const { Provider, Consumer } = React.createContext()
复制代码
- 使用Provider组件作为父节点
class ContextComponent extends React.Component {
render() {
return (
// 使用Provider包裹,通过value传值
<Provider value="hello, child">
<div>
contextComponent
<Node />
</div>
</Provider>
)
}
}
复制代码
- 设置value属性,表示要传递的数据
class ContextComponent extends React.Component {
render() {
return (
// 使用Provider包裹,通过value传值
<Provider value="hello, child">
<div>
contextComponent
<Node />
</div>
</Provider>
)
}
}
复制代码
- 通过Consumer组件接收数据,Consumer组件里面定义回调函数
class Node extends React.Component {
render() {
return (
<div>
node
<SubNode />
</div>
)
}
}
class SubNode extends React.Component {
render() {
return (
<div>
subNode
<Child />
</div>
)
}
}
class Child extends React.Component {
render() {
return (
// 使用Consumer包裹,定义回调接收数据
<Consumer>
{
data => <div>child:contextComponet提供的数据 -- {data}</div>
}
</Consumer>
)
}
}
复制代码
五、porps深入
children属性
- 表示组件标签的子节点,当组件标签有自节点的时候,props就会有该属性
- children属性和普通的props一样,值可以为任意值(文本,React元素,组件,函数)
class PropsDeep extends React.Component {
render() {
return (
<div>
parent
<Child>子节点</Child>
</div>
)
}
}
class Child extends React.Component {
render() {
return (
<div>
child ---
{this.props.children}
</div>
)
}
}
复制代码
props校验
- 对于组件来说,props是外来的,无法保证组件使用者传入什么格式的数据,所以需要进行校验
- props校验:允许在创建组件的时候,就指定props的类型、格式等
使用步骤
- 安装包prop-types(npm i porp-types/yarn add prop-types)
- 导入prop-types包
- 使用
组件名.propTypes = {}
来给组件的props添加校验规则 - 校验规则通过PropType对象来指定
- 约束规则
- 常见类型:array、bool、func、number、object、string
- React元素类型:element
- 必传项:isRequired
- 特定结构的对象:shape({})
PropsCheck.propTypes = { // 属性num的类型:数值(number) num: PropTypes.number, // 属性fn的类型:函数(func)并且为必传项 fn: PropTypes.func.isRequired, // 属性tag的类型:React元素(element) tag: PropTypes.element, // 属性obj的类型:对象({userName: 'yusong', age: 18}) obj: PropTypes.shape({ userName: PropTypes.string, age: PropTypes.number }) } 复制代码
六、组件的生命周期
只有类组件(有状态组件)才有生命周期
创建时(挂载阶段)
执行时机:组件创建时(页面加载时)
执行顺序:
- constructor()
- 创建组件时,最先执行
- 作用:
- 初始化state
- 为事件处理程序绑定this
- render()
- 每次组价渲染都会触发
- 作用
- 渲染UI(
不能调用setState(),不然会导致递归
)
- 渲染UI(
- componentDidMount()
- 组件挂载(完成DOM渲染后)
- 作用
- 发送网络请求
- DOM操作
钩子函数 | 触发时机 | 作用 |
---|---|---|
constructor | 创建组件时,最先执行 | 1、初始化state 2、为时间处理程序绑定this |
render | 每次组价渲染都会触发 | 渲染UI(不能调用setState(),不然会导致递归 ) |
componentDidMount | 组件挂载(完成DOM渲染后) | 1、发送网络请求 2、DOM操作 |
更新时(更新阶段)
执行时机:
- 调用setState()
- 调用forceUpdate()
- 组件接收到新的props
执行顺序
- render()
- 每次组件渲染都会触发
- 作用
- 渲染UI(与挂载阶段是同一个render)
- componentDidUpdate()
- 组件更新(完成DOM渲染后)
- 作用
- 发送网络请求
- DOM操作
- 注意点:如果要setState()必须放在一个if条件中
class LifeCycle extends React.Component { state = { count: 0, } changeCount = () => { this.setState({ count: this.state.count + 1, }) } render() { return ( <div> <Child1 count={this.state.count} /> <Child2 changeCount={this.changeCount} /> </div> ) } } class Child1 extends React.Component { // prevProps上一次的props componentDidUpdate(prevProps) { console.log('更新完毕', prevProps) // 在改钩子里面调用setState()一定要加判断条件,否则会导致递归报错 // 判断前一次的props是否与当前的props相等 if (prevProps.count !== this.props.count) { this.setState({}) } } render() { return ( <div> child1:{this.props.count} </div> ) } } class Child2 extends React.Component { render() { return ( <div> child2 <button onClick={() => this.props.changeCount()}>+1</button> </div> ) } } 复制代码
钩子函数 | 触发时机 | 作用 |
---|---|---|
render | 每次组件渲染都会触发 | 渲染UI(与挂载阶段是同一个render) |
componentDidUpdate | 组件更新(完成DOM渲染后) | 1、发送网络请求 2、DOM操作 3、注意点:如果要setState()必须放在一个if条件中 |
卸载时(卸载阶段)
执行时机
- 组件从页面中消失
执行顺序
- componentWillUnmount
- 组件卸载(从页面中消失)
- 作用
- 执行清理工作(比如:清理定时器等)
钩子函数 | 触发时机 | 作用 |
---|---|---|
componentWillUnmount | 组件卸载(从页面中消失) | 执行清理工作(比如:清理定时器等) |
其他的钩子函数介绍(在后面文章再详细介绍)
旧版完整生命周期钩子
新版版完整生命周期钩子
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END