Javascript 不带类的有状态组件

Javascript 不带类的有状态组件,javascript,reactjs,functional-programming,Javascript,Reactjs,Functional Programming,在React中,我们可以将组件编写为纯函数。但是,问题是,由于缺少生命周期挂钩和状态,因此不能将其用作有状态组件。因此,我想知道是否有任何方法可以在不使用类的情况下创建有状态组件 我找到的是createClasshelper。但是,React已将此帮助程序移动到其发行版15.5.0中自己的包中。此外,他们建议您将它们迁移到JavaScript类,因为类现在是在React中创建组件的首选方式。因此,我认为使用这个助手不是一个好主意 另一方面,Facebook建议使用高阶组件(HOC),这是Reac

在React中,我们可以将组件编写为纯函数。但是,问题是,由于缺少生命周期挂钩和状态,因此不能将其用作有状态组件。因此,我想知道是否有任何方法可以在不使用类的情况下创建有状态组件

我找到的是
createClass
helper。但是,React已将此帮助程序移动到其发行版
15.5.0
中自己的包中。此外,他们建议您将它们迁移到JavaScript类,因为类现在是在React中创建组件的首选方式。因此,我认为使用这个助手不是一个好主意

另一方面,Facebook建议使用高阶组件(HOC),这是React中用于重用组件逻辑的高级技术。HOC本身不是React API的一部分。它们是从React的组成性质中产生的一种模式。但是,我找不到一种方法来创建没有类的公共有状态组件


有人经历过这个吗?有没有办法将React用作纯功能性解决方案?

在不使用类的情况下编写有状态组件肯定是一些开发人员的选择。我建议使用“recompose”,它具有良好且简单的实现,可以编写没有类的有状态组件,同时应用本地和来自存储的状态。以下是一个例子:

import compose from 'recompose/compose'
import withState from 'recompose/withState'
import withProps from 'recompose/withProps'

Pure.js

function MyComponent(props) ({

  local: { prop1, prop2 },
  setProp1 
})

  return <div>{prop1}</div>
}

const defaultState = {
  prop1: false,
  prop2: false
}

const enhance = compose(
  withState('local', 'updateLocal', defaultState),
  withProps(({ local: { prop1, prop2 }, updateLocal }) => ({
    setProp1: (newValue) => updateLocal(state => ({...state, prop1: newValue }))
  })))

export default enhance(MyComponent)
从“重新组合/组合”导入组合
使用状态从“重新组合/使用状态”导入
从“重新组合/withProps”导入withProps
Pure.js
功能MyComponent(道具)({
本地:{prop1,prop2},
setProp1
})
返回{prop1}
}
const defaultState={
建议1:错误,
建议2:错误
}
常数增强=合成(
带状态('local','updateLocal',defaultState),
withProps({local:{prop1,prop2},updateLocal})=>({
setProp1:(newValue)=>updateLocal(state=>({…state,prop1:newValue}))
})))
导出默认增强(MyComponent)
也许会变得很方便。看看下面的例子

在局部变量中保存状态:

import React from "react"
import instance from "react-instance"

const App = instance(({ forceUpdate }) => {
  let time = 0

  const timer = setInterval(() => {
    time++
    forceUpdate()
  }, 100)

  return {
    render() {
      return time
    },
    unmount() {
      clearInterval(timer)
    },
  }
})
import React from "react"
import instance from "react-instance"

const App = instance(instance => {
  instance.state = { time: 0 }

  const timer = setInterval(() => {
    instance.setState({ time: instance.state.time + 1 })
  }, 100)

  return {
    render() {
      return instance.state.time
    },
    unmount() {
      clearInterval(timer)
    },
  }
})
在组件状态下保存状态:

import React from "react"
import instance from "react-instance"

const App = instance(({ forceUpdate }) => {
  let time = 0

  const timer = setInterval(() => {
    time++
    forceUpdate()
  }, 100)

  return {
    render() {
      return time
    },
    unmount() {
      clearInterval(timer)
    },
  }
})
import React from "react"
import instance from "react-instance"

const App = instance(instance => {
  instance.state = { time: 0 }

  const timer = setInterval(() => {
    instance.setState({ time: instance.state.time + 1 })
  }, 100)

  return {
    render() {
      return instance.state.time
    },
    unmount() {
      clearInterval(timer)
    },
  }
})

一个新的特性支持这一点,称为React hooks。从:

挂钩是React 16.8中新增的一项功能。它们允许您在不编写类的情况下使用状态和其他React特性

一个简单的例子:

import { useState } from 'react';

function Example() {
  // Declare a new state variable, which we'll call "count"
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}
从'react'导入{useState};
函数示例(){
//声明一个新的状态变量,我们称之为“count”
const[count,setCount]=useState(0);
返回(
您单击了{count}次

设置计数(计数+1)}> 点击我 ); }

有关如何使用生命周期的示例,请查看

我尝试在不使用es6类的情况下创建一个名为Comp的简单有状态组件


基本上,我将Comp函数的原型(我们的有状态组件)链接到React.component的原型对象,并将其传递给Comp的props以正确初始化它。之后,您可以使用Comp.prototype上React.Component对象的每个函数。我举了一些例子。我不知道这是否是在monad中使用react

的“最javascript”方式中的最佳方式。你有使用函数式编程语言的经验吗?可以使用纯函数模拟有状态操作,只需将新状态作为返回值之一返回,然后在下次调用函数时将该状态作为参数之一使用。这种抽象称为“状态单子”。是的,但是反应生命周期挂钩呢?你可以使用镜头或光标。这表示一对函数,它们可以读取和替换集中式状态的某些子集。一个库的例子可以帮助你实现这一点,这很好,我不知道。顺便说一句,这个库也使用了
createClass
助手。我这辈子都在哪里使用这个库。谢谢!那你的钩子呢?你能用它吗?@mattias,我不确定生命周期事件是否也可以附加。到目前为止,我还没有看到实现。您可能希望访问库以了解更多详细信息。它不再是实验性的,因此您可能希望更新您的答案注意React
16.8
已过时,并且具有挂钩支持。您必须在一年内再次更新它,删除“new”(新)一词。)