专业编程基础技术教程

网站首页 > 基础教程 正文

一起学React-组件定义和组件通讯

ccvgpt 2024-08-15 20:26:11 基础教程 6 ℃

前言

人总要找方法逼自己进步,就像我们,用写作的方式督促自己。有兴趣的话,欢迎一起用写作逼自己做自己“不敢做”!

这已经是《一起学React》第二篇文章了:

一起学React-组件定义和组件通讯

一起学React-元素渲染和生命周期

React主打函数式编程,配合上JSX语法,基本上可以把每个模块都封装为单独组件,用组件一时爽,一直用一直爽。

1.函数式组件

在React中最简单的即是创建一个函数式,没有生命周期的组件,这与 Vue 的单文件 .vue 一个完整生命周期组件不同,举个例子。

// 定义weblcome 组件
function Welcome(props) {
 return <h1>Hello, {props.name}</h1>;
}

这里的props属性对象是React中组件单向数据传递的唯一标示,在函数式组件中,我们可以通过 props.name 来获取 其他组件传递的name 属性,这点和Vue是没有本质区别的。

// 子组件 获取name属性
function Welcome(props) {
 return <h1>Hello, {props.name}</h1>;
}
// 父组件传入name属性
const element = <Welcome name="Sara" />;
ReactDOM.render(
 element,
 document.getElementById('root')
);

2.class 组件

函数式组件由于没有生命周期的定义,虽然简洁,但是拓展方面较差,我们把上面的welcome,改写为class组件

class Welcome extends React.Component {
 render() {
 return <h1>Hello, {this.props.name}</h1>;
 }
}

welcome继承自React.Component 组基类,在class组件中,作用域为当前组件,所以使用this对象来代替。

class组件有完整的生命周期,当组件插入到DOM中时,会依次调用生命周期函数。

render() 是class组件中必须实现的方法

当每次render 被触发是都会检查 this.props 和this.state 的变化、

同理适用于任何class 组件的检查方式

所以在处理函数时,要考虑好应该在组件生命周期的那一步触发,反之容易凉凉,或影响性能

3.顺滑的组件抽取方式

每个class组件, 无论单独调用,还是循环调用,都有自己的生命周期和单独的state。

举个实际场景。

比如:维护一个列表,列表中有, 全部,完成,失败,进行中,等状态type。

首先想到的是维护一个type 数组,然后通过map 循环的方式来产生列表

好处是数据操作方便,缺点就是和其他 n个列表公用一个state ,没有办法将其中某个item的状态区分开来

通过维护一个item组件,每个item都有自己的state,随心所欲的操作

all in all 每个通过map 循环的item, 都可以根据业务考虑封装为一个组件,因为你定义的时候就是一个变量, 不会像vue 通过v-for 指令渲染,后期抽离的成本不是很大。

Warning 如果shouldComponentUpdate 返回false 则不会render

当组件的props 或者state 变化时会触发更新。 会依次执行下面的生命周期

  1. static getDerivedStateFromProps()
  2. shouldComponentUpdate() // 必要时来做性能优化,在第一期提过
  3. render() // 必须要用
  4. getSnapshotBeforeUpdate()
  5. componentDidUpdate() // 最常用的组件状态更新判断

最比较常用的除了 componentDidMount() 之外,还有 componentDidUpdate() 来判断组件是否需要更新。

4.使用propTypes进行类型检查

propsTypes 是React友好的类型检查,通常和组件搭配使用。

使用方法非常简单,上图

二、 组件通讯方式

在单向通信中,最常见的就是通过prop方式。

父 - 子

子组件定义好item参数

父组件按照propTyes进行传参

子组件通过 this.props.item 取值

子 - 父

// 子组件
HomeItem.defaultProps = {
 item: {},
 // 定义回调函数
 fetchData: () => {},
};
HomeItem.propTypes = {
 item: PropTypes.object,
 fetchData: PropTypes.func,
};
// 在子组件
 handleSuccessDel = () => {
 const successUrl = {
 url: `/xq/statuses/destroy/${this.state.uid}.json`,
 params: {},
 };
 const draftUrl = {
 url: '/xq/statuses/draft/delete.json',
 params: { id: this.props.item.textId },
 };
 const delUrl = this.props.item.typeName === '草稿' ? draftUrl : successUrl;
 httpClient.post(delUrl.url, delUrl.params).then((res) => {
 if (res.success) {
 this.setState({
 showModal: false,
 });
 Toast({ text: '删除成功', type: 'success' });
 // 通过参数执行父组件传过来的callback 进而引起父组件状态改变
 this.props.fetchData();
 }
 }).catch((err) => {
 console.error(err);
 });
 };

尾声

没啥好说的,学就完了…

最近发表
标签列表