微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

从 react-redux 到 react-final-form 的迁移

如何解决从 react-redux 到 react-final-form 的迁移

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

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

我遵循了 react-final-form 文档,并尝试像这样更改它:

获取表格:

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,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,showNotification,refreshView
})(AdminButton)

那么谁能帮我理解我做错了什么?非常感谢!

解决方法

您不能在 import React from "react"; import { connect } from "react-redux"; import * as courseActions from "../../redux/actions/courseActions"; import PropTypes from "prop-types"; import { bindActionCreators } from "redux"; import history from './history' class CoursesPage extends React.Component { state = { course: { title: "",},}; handleSubmit = (event) => { event.preventDefault(); this.props.actions.loadCourses.createCourse(this.state.course).then(() => { alert('Inside Promise') history.push('/AllCourses'); //This doesn't get executed. }; render() { return ( <div> <form onSubmit={this.handleSubmit}> <h2>Courses</h2> <h3>Add Course</h3> <input type="submit" value="Add Course" /> {this.props.courses.map((course) => ( <div key={course.title}>{course.title}</div> ))} </form> <hr /> </div> ); } } CoursesPage.propTypes = { courses: PropTypes.array.isRequired,actions: PropTypes.object.isRequired,}; function mapStateToProps(state) { return { courses: state.courses,}; } function mapDispatchToProps(dispatch) { return { actions: { loadCourses: bindActionCreators(courseActions,dispatch),}; } export default connect(mapStateToProps,mapDispatchToProps)(CoursesPage); Action Code: import * as types from "./actionTypes"; export function createCourse(course) { return { type: types.CREATE_COURSE,course }; } Reducer: import * as types from "../actions/actionTypes"; export default function courseReducer(state = [],action) { debugger; switch (action.type) { case types.CREATE_COURSE: return [...state,{ ...action.course }]; default: return state; } } history.js import createHistory from 'history/createHashHistory' export default createHistory() 上下文之外使用 useFormuseFormState。也就是说,尝试将您的组件包装在 Form 之类的

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。