如何从重组转换为钩子?

Posted

技术标签:

【中文标题】如何从重组转换为钩子?【英文标题】:How to convert from recompose to hooks? 【发布时间】:2019-08-23 05:37:32 【问题描述】:

我的公司正在使用 recompose 作为我们的状态管理工具。我们正在重构我们的应用程序以使用钩子。对于下面的代码,如何将 recompose 组件替换为 react hook 组件?

我理解withState变成useState,如:

withState('something', 'setSomething', null)

变成

const [something, setSomething] = useState(null);

withPropswithHandlerscomposehoistStaticslifecycle 会变成什么?

mapStateToPropsmapDispatchToProps 将如何工作?

import  compose, hoistStatics, withHandlers, withState, withProps, lifecycle  from 'recompose';
import  connect  from 'react-redux'
import myComponent from './myComponent'

const mapStateToProps = (state, props) => 
  return 

  
;

const mapDispatchToProps = (dispatch) => 
  return bindActionCreators(

  , dispatch)
;

const enhancer = compose(
  connect(mapStateToProps,mapDispatchToProps),
  withProps(props => (
    myProp: props.myProp,
  )),
  withState('something', 'setSomething', null),
  withState('somethingElse', 'setSomethingElse', null),
  withHandlers(
    myFunction: () => () => 
      console.log(`I need help`);
    
  ),
  lifecycle(
    componentDidMount() 

    ,
    componentDidUpdate() 

    
  )
);

export default hoistStatics(enhancer)(myComponent);

【问题讨论】:

【参考方案1】:

引用丹·阿布拉莫夫:

为了提高工作效率,您需要“思考效果”,以及他们的心理 模型更接近于实现同步而不是响应 生命周期事件。

我们不能 1:1 替换 hooks 和 hocs,因为它们是不同的编程模型。 不过,我们可以尝试通过以下方式迁移:

withProps - 可以在组件内替换为 const

withHandlers - 可以替换为组件内的箭头函数

lifecycle - https://***.com/a/55502524/3439101

一个简单的例子(不是所有的情况):

hocs

const enhancer = compose(
  withProps(props => (
    myProp: props.myProp,
  )),
  withState('something', 'setSomething', null),
  withHandlers(
    myFunction: () => () => 
      console.log(`I need help`);
    
  ),
  lifecycle(
    componentDidMount() 
      console.log('mounted')
    
  )
);

带有挂钩

const MyComponent = props => 
  const [something, setSomthing] = useState(null)

  useEffect(() => 
    console.log('mounted')
  , [])

  const myProp = props.myProp

  const myFunction = () => 
    console.log(`I need help`);
  

【讨论】:

const myProp = props.myProp -> 如果该道具与其他道具相关计算并且这些道具需要更新为最新?因为它是 const 它不应该更新我错了。???【参考方案2】:

你说得对,withState 可以替换为useState

对于 Redux 部分,React 建议继续以您一直使用它的方式使用 API,但您应该从 compose 中删除它。在react-redux v7 中将为此实现一个新的钩子。

现在withHandlers,可以用普通的javascript函数替换,将其添加到您的组件或任何其他文件中

之前:

withHandlers(
    myFunc() => () => console.log('hello')
)

现在:

const myFunc = () => console.log('hello')

最后但同样重要的是,componentDidMountcomponendDidUpdate 需要替换为 useEffect。在这里将有一些阅读以了解其工作原理,但这并不难。您将创建基本上是运行每个渲染的函数的效果,如果您希望它仅在某些内容发生更改时运行,您可以传递第二个参数,类似于 componentDidUpdate 或如果您只想运行一次类似于componentDidMount。不要将效果视为生命周期事件的替换,但您可以获得相同的结果。看看this article我发现它很有用。

可用的钩子很少,我发现useContextuseCallbackuseReducer 非常好用。

【讨论】:

非常感谢!您的回答和文章非常有用。你知道什么可以代替withPropshoistStatics吗?

以上是关于如何从重组转换为钩子?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用钩子将 React 类组件转换为功能组件

使用钩子将类组件转换为函数式

为啥我不能将其转换为自定义的 React 钩子?

js 对象里 增加删除一项字段 (把某对象里的数组转换为字符串,重组为新对象)

如何使用 PyTorch 正确实现数据重组?

VueJS JS-only 转换钩子需要 setTimeout 才能使 CSS 转换工作