【问题标题】:How can I insert a reduxForm component without starting too many calls如何在不启动太多调用的情况下插入 reduxForm 组件
【发布时间】:2018-08-19 07:46:39
【问题描述】:

我总体上使用的是 MERN 堆栈,但我认为这个问题只适用于 react 和 redux 形式。

每当我包含一个表单以在我的用户仪表板中添加项目时,我最终都会得到 Uncaught Error: Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.

首先,我根本没有显式调用 componentWillUpdate 或 componentDidUpdate,所以我很难找到问题。如果我停止开发服务器,比如CTRL+C,它有时会为我呈现(现在不可用的)表单。

我试过了(都失败了):

  • 只包含没有处理程序的表单
  • 包含表单并在仪表板上处理它
  • 包含表单并在表单上处理它
  • 删除基于此somewhat similar problembind(this) 的所有调用

我有类似的 redux-forms(在他们的容器中处理)可以很好地用于注册和登录

UserDashboard.js当我添加表单时发生错误并且没有它也可以正常工作

import React, { Component } from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';

import * as actions from '../../actions';
import Cupcakes from './cupcakes';
import Monkeys from './monkeys';
import AddMonkeyForm from './add_monkey_form'


class UserDashboard extends Component {


    // handleSubmit({name}) {
    //     console.log("handleSubmitMonkey with", {name})
    //   //this.props.createMonkey({user, name})
    // }

    render() {
        return (
            <div className="container">
                <div className="section">
                    <h1>Hi: {this.props.user.name}</h1>
                </div>
                <div className="section">
                    <h2>Monkeys</h2>
                    <div className="row">
                        <div className="col m6 s12">
                        <h4>Add a new monkey</h4>
                        <AddMonkeyForm /> // If I take this out, everything works, it fails whether or not I add a handle submit function
                        </div>
                        <div className="col m6 s12">Existing monkeys</div>
                    </div>
                </div>
                <div className="section">
                    <h2>Cupcakes</h2>
                    <div className="row">
                        <div className="col m6 s12">Add a new cupcake</div>
                        <div className="col m6 s12">Existing cupcakes</div>
                    </div>
                </div>
            </div>
        );
    }
}

function mapStateToProps(state) {
    const user = state.auth.user;
    const cupcakes = state.userdata.cupcakes;
    const monkeys = state.userdata.monkeys;
    return { user: user, monkeys: monkeys, cupcakes: cupcakes };
}

export default connect(mapStateToProps, actions)(UserDashboard);

// <AddMonkeyForm onSubmit={this.handleSubmit.bind(this)}/>

AddMonkeyForm.js 导致错误 - 无论我尝试在 AddMonkeyForm 或 UserDashboard 中调用 handlesubmit 还是根本不调用,这个都会失败。

import React, { Component } from 'react';
import { reduxForm, Field } from 'redux-form';
import { connect } from 'react-redux';

import renderTextField from '../helpers/form_helpers';
import { createMonkey } from '../../actions';

class AddMonkeyForm extends Component {
    onSubmit(values) {
        console.log('trying to submit MONKEY');
        // this.props.createMonkey(values, () =>{
        //     this.props.history.push('/');
        // });
    }
    render() {
        const { handleSubmit } = this.props;

        return (
            <div className="section">
                <form onSubmit={handleSubmit(this.onSubmit.bind(this))}>
                    <Field
                        label="Name"
                        name="name"
                        placeholder="Fluffy"
                        component={renderTextField}
                        type="text"
                    />

                    <button
                        className="btn-large dark-primary-color"
                        type="submit"
                    >
                        Add Monkey
                        <i className="material-icons right">done</i>
                    </button>
                </form>
            </div>
        );
    }
}

const validate = values => {
    const errors = {};

    if (!values.name) {
        errors.name = 'Please enter monkey name';
    }

    return errors;
};

export default reduxForm({
    form: 'addmonkey',
    validate
})(AddMonkeyForm);

//})(connect(null, { createMonkey })(AddMonkeyForm));

actions.js 中我最终会用这个调用的动作

export function createMonkey(userid, name) {
    return function(dispatch) {
        const url = `${USER_API_URL}/${userid}/monkey/new`;
        const request = axios.post(url, {
            headers: { authorization: `Bearer ${localStorage.getItem('token')}` },
            name
        });
        request
            .then(response => {
                console.log("createMonkey has RESPONSE", response.data.createdMonkey)
                dispatch({
                    type: GET_USER_MONKEYS,
                    payload: response.data.createdMonkey
                });
            })
            // If request is bad...
            // -Show an error to the user
            .catch(() => {
                console.log('error');
            });
    };
}

**usergetters.js reducer,最终将根据表单更新 userdata.monkeys 状态。

import { GET_USER_CUPCAKES, GET_USER_MONKEYS } from '../actions/types'

const initialUserData = [{cupcakes: [], monkeys: []}]

export default function userGetterReducer(state = initialUserData, action) {
  switch (action.type) {
    case GET_USER_CUPCAKES:
      return {...state, cupcakes: action.payload}
    case GET_USER_MONKEYS:
      return {...state, monkeys: action.payload }
    default:
      return state
  }
}

该项目在 github 上。这个特定的错误分支是addmonkeyform1,如果由于某种原因你最终在master上,它看起来会与这里显示的不同。 Go to Project on Github

【问题讨论】:

    标签: reactjs redux redux-form


    【解决方案1】:

    我取消了项目并试图找到多个调用的来源。我不确定它来自哪里。如果我发现任何进一步的东西,我会更新。

    与此同时,您可以在 App.js 中执行以下操作:

    shouldComponentUpdate(nextProps, nextState) {
      console.log('shouldComponentUpdate');
      return nextState !== this.state;
    }
    

    如果状态没有改变,这将防止重新渲染。

    【讨论】:

    • 好的。我添加了它,并且不断刷新停止。我用这个名为 addmonkeyform2 的更改创建了一个新分支,我从现在开始工作。谢谢你的主意。我想了解导致问题的原因,但只要停止它就可以让我更接近于使应用程序正常工作。 :)
    【解决方案2】:

    在呈现表单时,您会立即调用 handleSubmit(...)。我假设您只想在实际提交表单时调用它,因此您应该更改此行:

    <form onSubmit={handleSubmit(this.onSubmit.bind(this))}>
    

    到这样的事情:

    <form onSubmit={(values) => methodYouWantToCallWhenTheFormIsSubmitted(values)}>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-09
      • 2011-09-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多