学习react的第五天,持续更新中 关注不迷路!!!
函数柯里化
在上一篇文章中,学习了react如何收集表单数据,但定义太多的函数方法
先说一下高阶函数,函数柯里化的定义
高阶函数:如果有一个函数符合下面两个规范的任何一个,那该函数就是高阶函数
- 若A函数,接收的参数是一个函数,那么A就是高阶函数
- 若A函数,调用的返回值依然是一个函数,那么A就可以称为高阶函数
常见的高阶函数:promise,setTimeout,arr.map() 等等
函数的柯里化:通过函数调用继续返回函数的方式,实现多次接收参数最后统一处理的函数编码形式
// 连续返回函数
function a(a){
return function(b){
return function(c) {
return console.log(a + b + c);
}
}
}
a(1)(2)(3) // 6
再回顾下vue的函数柯里化
// 定义一个普通的函数
function add(a, b, c) {
return a + b + c;
}
// 使用柯里化转换为接收单一参数的函数
function curriedAdd(a) {
return function(b) {
return function(c) {
return a + b + c;
};
};
}
// 使用curriedAdd函数
const add2 = curriedAdd(2);
const add5 = add2(3); // 等价于 add(2, 3, c)
console.log(add5(4)); // 输出 9
在Vue中,函数柯里化(Currying)是一种函数式编程的技术,它允许你将一个接受多个参数的函数转换成一系列只接受单一参数的函数。这种转换使得函数更加灵活,可以更容易地进行组合和复用。
那开始今天的学习 ————— react的函数柯里化
// 现用现取 就是非受控组件
render() {
return (
<form onSubmit={this.getQuer}>
用户名: <input onChange={this.setFrom('username')} type="text" name="username" />
密码: <input onChange={this.setFrom('password')} type="password" name="password" />
<button>提交</button>
</form>
)
}
getQuer = (event) => {
// 调用原生对象上 阻止表单的默认提交
event.preventDefault()
console.log(this.state);
}
// 保存数据到状态中
setFrom(data) {
// 返回一个回调函数
return (event) =>{
this.setState({[data]: event.target.value})
}
}
在这个例子中,setFrom
函数接受一个data
参数,并返回一个函数,这个函数接受event
参数接受用户名参数,返回渲染组件的JSX。
Vue和React都支持函数柯里化,但它们之间存在一些细微的差异。
-
语法和使用方式:
- Vue通常更倾向于使用JavaScript原生的柯里化技术,因为Vue本身并没有提供专门的柯里化函数。你可以直接使用JavaScript中的
Function.prototype.bind
、箭头函数或者手动编写柯里化函数来实现。 - React并没有内置的柯里化函数,但你可以在React中以相同的方式使用JavaScript原生的柯里化技术。
- Vue通常更倾向于使用JavaScript原生的柯里化技术,因为Vue本身并没有提供专门的柯里化函数。你可以直接使用JavaScript中的
-
组件的构建:
- 在Vue中,你可以通过将组件定义为函数,并在组件内部使用柯里化技术来管理状态、props和事件处理逻辑。
- 在React中,组件通常是类或函数,并且柯里化可以被应用于函数式组件的构建,也可以用于处理事件处理函数等。
-
生态系统的差异:
- 由于Vue和React是两个不同的框架,它们的生态系统也有所不同。在Vue生态系统中可能会有一些专门用于柯里化的库或者插件,而在React生态系统中可能有一些更多的函数式编程库,这些库通常也支持柯里化。
虽然Vue和React在柯里化的实现上有些许差异,但基本概念是相同的:将一个接受多个参数的函数转换成一系列只接受单一参数的函数。这使得函数更具有灵活性、可组合性和可复用性,从而更容易构建复杂的应用程序。
补充一下不用函数柯里化的写法
// 现用现取 就是非受控组件
render() {
return (
<form onSubmit={this.getQuer}>
用户名: <input onChange={(event) => {this.setFrom('username', event.target.value) }} type="text" name="username" />
密码: <input onChange={(event) => {this.setFrom('password', event.target.value)}} type="password" name="password" />
<button>提交</button>
</form>
)
}
getQuer = (event) => {
// 调用原生对象上 阻止表单的默认提交
event.preventDefault()
console.log(this.state);
}
// 保存数据到状态中
setFrom(dataType,value) {
this.setState({[dataType]:value})
}
组件的生命周期
在React中,组件的生命周期指的是组件从创建到销毁期间所经历的一系列阶段。这些生命周期方法可以让你在特定的时刻执行代码,以便在组件的不同阶段执行逻辑、处理数据等。React 16.3以后,生命周期方法被归纳为三个阶段:挂载(Mounting)、更新(Updating)、卸载(Unmounting)。以下是React组件生命周期的概要:
-
挂载阶段(Mounting):
constructor()
: 在组件被创建时调用,用于初始化状态和绑定事件处理函数。static getDerivedStateFromProps()
: 在组件接收到新的 props 或者 state 时调用,用于根据新的 props 或者 state 更新组件的状态。render()
: 渲染组件的内容,这是一个必须实现的方法。componentDidMount()
: 在组件被挂载到 DOM 后立即调用,用于执行一次性操作,如获取远程数据、订阅事件等。
-
更新阶段(Updating):
static getDerivedStateFromProps()
: 同挂载阶段,用于根据新的 props 或者 state 更新组件的状态。shouldComponentUpdate()
: 在组件接收到新的 props 或者 state 时调用,用于判断是否需要重新渲染组件,默认返回 true。render()
: 重新渲染组件的内容。getSnapshotBeforeUpdate()
: 在组件更新 DOM 之前调用,可以在此方法中获取当前 DOM 的快照,通常用于获取滚动位置等信息。componentDidUpdate()
: 在组件更新完成后调用,用于执行一些与 DOM 相关的操作,例如处理动画效果、更新 DOM 元素。
-
卸载阶段(Unmounting):
componentWillUnmount()
: 在组件即将被卸载时调用,用于执行一些清理操作,如取消订阅事件、清除计时器等。
除了上述方法外,还有一些已经被废弃的生命周期方法,如 componentWillMount()
、componentWillReceiveProps()
等。在新的React版本中,不建议再使用这些已经废弃的方法,而是使用上述新的生命周期方法来处理组件的生命周期。
class A extends React.Component{
constructor(props){
console.log("A --- constructor")
super(props);
this.state = {num:1}
}
add = () => {
let {num} = this.state;
this.setState({num:num+1});
//强制更新
//this.forceUpdate();
}
render(){
console.log("A --- render");
return (
<div>
<h1>这个是第{this.state.num}个</h1>
<B name = {this.state.num}/>
<button onClick = {this.add}>点击加一</button>
</div>
)
}
//在render之前执行
componentWillMount(){
console.log("A --- componentWillMount");
}
//在render之后执行
componentDidMount(){
console.log("A --- componenetDidMount");
}
//更新操作 setState之后执行,判断是否可以更新(true可以,false不可以)
shouldComponentUpdate(){
console.log("A --- shouldComponentUpdate");
return true;
}
// 组件更新之前
componentWillUpdate(){
console.log("A --- componentWillUpdate");
}
//组件更新之后
componentDidUpdate(){
console.log("A --- componentDidUpdate");
}
//卸载组件之后
componentWillUnmonut(){
console.log("A --- componentWillUnmonut");
}
}
class B extends React.Component{
render(){
return(
<div>
<h1>这个是B组件,传递过来的是:{this.props.name}</h1>
</div>
)
}
//父组件进行了更新,子组件先执行这个
componentWillReceiveProps(){
console.log("A --- componentWillReceiveProps");
}
}
ReactDOM.render(<A />,document.getElementById("div"));
高版本以后
class A extends React.Component{
constructor(props){
console.log("A --- constructor")
super(props);
this.state = {num:1}
}
add = () => {
let {num} = this.state;
this.setState({num:num+1});
//强制更新
//this.forceUpdate();
}
render(){
console.log("A --- render");
return (
<div>
<h1>这个是第{this.state.num}个</h1>
<button onClick = {this.add}>点击加一</button>
</div>
)
}
//必须是静态的
//必须有返回值(Null或者state对象)
//如果返回的是state对象,里面的将会对原有的state进行覆盖,并且不能修改【因为初始化,更新都会经过这个函数】
//给组件传递的参数,可以作为该方法的参数传递过来。因此可以让该参数作为state。
//也可以以props和state作为参数进行传递
static getDerivedStateFromProps(props){
console.log("A --- getDerivedStateFromProps",props);
return null;
}
//更新的时候调用,在render和componentDidUpdate之间
//必须返回一个快照
getSnapshotBeforeUpdate(){
console.log("A --- getSnapshotBeforeUpdate");
return null;
}
//在render之后执行
componentDidMount(){
console.log("A --- componenetDidMount");
}
//更新操作 setState之后执行,判断是否可以更新(true可以,false不可以)
shouldComponentUpdate(){
console.log("A --- shouldComponentUpdate");
return true;
}
//组件更新之后
componentDidUpdate(){
console.log("A --- componentDidUpdate");
}
//卸载组件之后
componentWillUnmonut(){
console.log("A --- componentWillUnmonut");
}
}
ReactDOM.render(<A />,document.getElementById("div"));