React 分享一

react 组件

最开始使用 React,是依靠官方文档的实例去熟悉它的语法,然后从 Hello World 开始;
在后来的项目中,用到了 函数组件 以及 类组件,以及后来React更新的 Hook组件;那儿就下来我们就来看一看这些组件使用的区别;

1 函数组件和类组件

1.1 语法
import React from 'react'
const Welcome = (props) => {
  return <h1>welcome, {props.name}</h1>
}
export default Welcome
// 这是一个纯函数组件
import React from 'react'
class Welcome extends React.Component {
  constructor(props) {
    super(props)
  }
  render() {
    return <h1>welcome, {this.props.name}</h1>
  }
}
export default Welcome
// 这是一个类组件

这两个版本虽然最后展现的效果是一样的,但是明显的不同是在语法上,函数组件是一个纯函数,它通过接受一个 props 返回一个 React 元素;而类组件是需要去继承 React.Compontent 并且创建一个 render 函数返回的 React 元素,这里看到类组件会多出一些代码;

1.2 状态管理

在函数组件中,因为函数组件是一个纯函数,所以不能在内部使用 setState,故函数组件也称作为无状态组件;
所以想要在组件中使用 state,可以选择使用类组件的方式,也可以将 state 在父组件中提升,然后通过 props 传递;
注:React做了版本的更新,使得在纯函数组件中可以通过useState钩函数管理state;

1.3 生命周期

在函数组件中,不能使用 React 的生命周期钩子函数,因为所有的生命周期钩子都继承于 React.compontent 中,所以想要在组件中使用生命周期,还是推荐使用类组件的方式;
注:React 做了版本的更新,使得在纯函数组件中可以通过 useEffect 去使用生命周期函数;
这里可以看到 React 的更新在偏向纯函数组件的使用;

2 Hook

在过去,像状态和生命周期函数这样的 React 特性只适用于基于类的组件;基于函数的组件无法访问状态和生命周期函数;
所以,在后来的版本中,React 对函数组件做了较大的优化,它使得函数组件能够以新的方式编写、重用和共享;
那么,我们就来学习一下 Hook

2.1 不要再循环中、条件和嵌套函数中调用 Hook,如果想要有条件的调用 Hook,可以在其内部书写;
useEffect(function persistForm() {
	if (name !== '') {
		localStorage.setItem('formData', name);
	}
})

注:这里是为了保证每次组件渲染时能够以相同的循序调用 Hook,这样也保证React能在多个useState和useEffect调用之间正确的保留 Hook 的状态;

2.2 仅从函数组件调用 Hook

不要从常规 JavaScript 函数中调用 Hook,仅从函数组件或自定义 Hooks 中调用 Hook;

遵循这一条规则,可以确保组件中的所有状态逻辑在源代码中都能清晰可见;

2.3 以正确的顺序创建函数组件

创建函数组件时,需要按照一定的顺序,以便于后期的维护和改进;

class Link extends React.Component {
    static methodsAreOk() {
		return true;
	}
	constructor(props) {
		super(props)
		this.state = {
			user = null
		}
	}
	componentDidMount() {
		console.log('component did mount')
	}
	componentDidUpdate() {
		console.log('component did update')
	}
	componentWillUnmount() {
		console.log('component will unmount')
	}
	render() {
		return <a href={this.props.url}>{this.props.text}</a>
	}
}
export default Link

以上是一个普通类组件创建的主体框架,首先调用了构造器并且启动了状态,然后编写生命周期,最后编写render方法

function App () {
	const [ user, setUser ] = useState(null)
	const [ name, setName ] = useState('Txt')
	useEffect(() => {
		console.log('component is mounted')
	}, [])
	// 此处一定要有状态才有执行,[]:为空执行一次,[name]:每次name变化时都会触发,[]:没有每次都会触发
	render <p>React component order</p>
}
2.4 useState 的用法可以和类组件的状态完全一致,不只用于单个值

很多的useState示例会向你展示如何通过声明多个变量来声明多个状态

const [name, setName] = useState('Txt')
const [email, setEmail] = useState('1327041751@qq.com')
const [age, setAge] = useState(28)

// 在这里, useState 既可以处理数组也可以处理对象。你依旧可以将相关数据分组为一个状态变量,如以下示例所示:

const [user, setUser] = useState(
  { name: 'Txt', email: '1327041751@qq.com', age: 28 }
)

// 注:使用useState的更新函数更新状态时,以前的状态会替换为新的状态;这与类组件的this.setStaate不同,在类组件中,新状态会与旧状态合并;
const [user, setUser] = useState(
	{ name: 'John', email: 'john@email.com', age: 28 }
)
setUser({ name: 'Txt' })

// result { name: 'Txt' }

// 因此,在Hook函数中,为了保留以前的状态,需要创建将当前状态值传递到自身中的回调函数来手动合并它;由于上面的示例已将 user 变量分配为状态值,因此可以将其传递给 setUser 函数,如下所示:
setUser((user) = > ({ ...user, name: 'Nathan' }))

// result is { name:'Nathan', email: 'john@email.com', age: 28 }

2.5 使用自定义 Hook 共享应用程序逻辑

React Hook 的发布,你可以将组件的逻辑提取到可重用的函数中作为自定义 Hook;

注:在类组件中不能使用 Hook 函数,如果要在类组件中使用,需要将类组件转化为函数;

2.6 使用 useContext 避免 props 的对层级传递(prop-drilling)

prop-drilling 是 React 应用程序中的常见问题,指的是将数据从一个父组件向下传递,经过各层级,直到到达指定的子组件,即使中间层组件不需要用到props,也需要接收并传递这个props;

export default function App () {
	const name = 'Txt'
	return <Hello name={name} />
}

function Hello (props) {
	return (
		<div>
			<h1>Hello World~ </h1>
			<Greeting name={props.name} />
		</div>
	)
}

function Greeting (props) {
	return 'My name is' + props.name
}

在 hook 中,App 的任何子组件都可以通过 useContext Hook 访问数据

import React, { useContext } from "react"

const appContext = React.createContext()
export default function App() {
	return (
		<appContext.Provider value={{ name: "Jane Doe" }}>
			<Hello />
		</appContext.Provider>
	)
}

function Hello() {
	return (
		<div>
			<h1>Hello World~ </h1>
			<Greeting />
		</div>
	)
}
function Greeting() {
	const context = useContext(appContext);
	return "My name is " + context.name;
}

当然 Hook 还有很多额外的Hook,这里就需要在实际的项目中去得到实践了,谢谢

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端e站

如果有所帮助,欢迎来杯奶茶

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值