【问题标题】:Migration from react-redux to react-final-form从 react-redux 迁移到 react-final-form
【发布时间】:2021-04-15 12:31:03
【问题描述】:

我将我的 react-admin 项目更新到 v3,此版本更新中的一些更改包括从 react-redux 迁移到 react-final-form,并且我正在尝试修复与此更改相关的一些错误。

我可能没有使用 react-final-form 对 - 我曾经使用 .change() 函数将我更改的输入字段值连接到商店。

我关注了react-final-form docs,并尝试像这样更改它:

获取表格:

const form = useForm()

然后使用它的.change 方法来更新我的用户界面:

form.change('isadmin', this.state.isAdmin)

但我收到此错误:

Uncaught (in promise) Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.

这是我的 AdminButton 组件的外观:

import React, { Component } from 'react'
import { connect } from 'react-redux'
import Switch from '@material-ui/core/Switch'
import { showNotification, fetchStart, fetchEnd, refreshView } from 'react-admin'
import { httpClient } from '../../dataProvider'
import { getFormValues } from 'redux-form'
import { useForm } from 'react-final-form'

const AdminButtonStyle = {
  zIndex: 2,
  display: 'inline-block',
  float: 'right',
  color: 'black'
}

class AdminButton extends Component {
  state = {
    isAdmin: this.props.formStates && this.props.formStates.isadmin
  }

  handleClick = async () => {
    const form = useForm()
    const { fetchStart, fetchEnd, record, showNotification } = this.props
    this.setState({
      isAdmin: !this.state.isAdmin
    })
    fetchStart()
    try {
      await httpClient(
        `api/users/${record.id}`,
        { method: 'PATCH', body: JSON.stringify({ isadmin: !this.state.isAdmin }) })
      form.change('isadmin', this.state.isAdmin)
      showNotification(`toggled user admin: ${this.state.isAdmin}`, 'success', { autoHideDuration: 10000 })
    } catch (err) {
      showNotification(`Error: ${err.data || err.message}`, 'warning', { autoHideDuration: 10000 })
    } finally {
      fetchEnd()
    }
  }

  render () {
    return <div style={AdminButtonStyle}>
      <span>Make Admin</span>
      <Switch
        checked={this.state.isAdmin}
        variant='raised'
        color='primary'
        size='large'
        onClick={this.handleClick}>
      </Switch>
    </div>
  }
}

function mapStateToProps (state) {
  return {
    formStates: getFormValues('record-form')(state)
  }
}

export default connect(mapStateToProps, {
  fetchStart,
  fetchEnd,
  showNotification,
  refreshView
})(AdminButton)

那么任何人都可以帮助我了解我做错了什么吗?非常感谢!

【问题讨论】:

    标签: react-redux react-admin react-final-form


    【解决方案1】:

    您不能在Form 上下文之外使用useFormuseFormState。也就是说,尝试将您的组件包装在 Form

    import { SimpleForm } from 'react-admin';
    
    <SimpleForm {...props}>
      ... // your component
    </SimpleForm>
    

    或者直接使用react-final-form组件

    import { Form } from 'react-final-form';
    
    <Form onSubmit={handleSubmit}>
      {({ handleSubmit }) => (
        <form onSubmit={handleSubmit}>
        ... // You component
        </form>
     )}
    </Form>
    

    然后在你的组件中,你可以使用useForm hook like

    import {useForm} from 'react-final-form';
    
    const AdminButton = () => {
      const form = useForm();
        
      const handleClick = async () => {
        ...
        form.change('isadmin', isAdmin);
        ...
      }
      ...
    }
    

    【讨论】:

    • 谢谢!它帮助我修复了一些错误,但我的问题仍然存在 - 你将如何使用更改功能?没有这样的钩子,我的 AdminButton 被包裹在 react-admin 的 SimpleForm 组件中
    • 看来你用对了,我已经更新了我的答案。
    【解决方案2】:

    您在 Class 组件中使用了 React 钩子。这是不允许的。尝试将您的组件转换为功能组件。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-05
      • 2021-07-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-19
      相关资源
      最近更新 更多