Code Monkey home page Code Monkey logo

Comments (29)

brennancheung avatar brennancheung commented on May 19, 2024 23

Editing Multiple Records link no longer working and can't find it in the current repo so just adding a short snippet for others running into same issue.

Basically, just use formKey.

<MyCustomComponent formKey={entity.id} />

That will make the form reducer use that so you don't get collisions.

from redux-form.

erikras avatar erikras commented on May 19, 2024 22

@steakchaser The way you do that in v6 is to change the form prop passed to your decorated component. Note: The form config parameter can be passed as a prop.

<MyRecord form={`record[${record.id}]}/>

from redux-form.

viotti avatar viotti commented on May 19, 2024 15

@jrutter maybe this helps: http://stackoverflow.com/a/37464048/2619107.

from redux-form.

erikras avatar erikras commented on May 19, 2024 5

You can see it in action here. If it fails to load, keep hitting reload. it's a feature!

from redux-form.

anhtran1906 avatar anhtran1906 commented on May 19, 2024 4

I used redux-form v6 and followed this instruction: http://stackoverflow.com/a/37464048/2619107 and it worked

from redux-form.

erikras avatar erikras commented on May 19, 2024 1

This is an important question. I'm thinking about it, not ignoring you. 😄 💭

from redux-form.

brianium avatar brianium commented on May 19, 2024 1

@cashkows-jason my solution was to create a container that could pass a selector function or selected values themselves. It is a little clunky in that it requires a container where you may otherwise not have one, but other than that it worked nicely

from redux-form.

bozdoz avatar bozdoz commented on May 19, 2024 1

Not sure if there's any documentation to this, but I've found naming forms with square brackets help to separate multiple forms:

{[0,1,2,3].map(i => (
  <FormComponent form={`namedForm[${i}]`} key={i} />
)}

Now state.form.namedForm is an Array which you can iterate.

from redux-form.

janmarek avatar janmarek commented on May 19, 2024

I like this library a lot. Unfortunately without this I cannot use it for all forms in my app.

from redux-form.

janmarek avatar janmarek commented on May 19, 2024

My ideas about API:

createFormReducerContainer(
    'sliceName',
    id => createFormReducer(id, ['field1', 'field2'])
)

@connect((state, props) => ({form: state.sliceName.get(props.itemId)}))
@reduxForm(props => ['sliceName', props.itemId], validationFunction)
class FormComponent {}

Something like that. Maybe you can come with something better.

from redux-form.

erikras avatar erikras commented on May 19, 2024

I think that the answer is that Redux isn't very good at this yet. It would be nice to be able to asynchronously load your list of objects, and then dynamically add/merge your reducers to the store.

  fetchRecords()
    .then(records => {
      reducers = {};
      records.forEach(record => {
        reducers[record.id] = createFormReducer(`widgets.${record.id}`, ['name', 'price']);
      });
      store.addReducers({
        widgets: reducers
      }); // merges this object into the master reducer
    });

Obviously, you'd then want to clean up with some sort of store.removeReducers() when you're done. Or maybe just have a "reducer reducer" that takes the current reducer and returns a new one to use. I see that getReducer() and replaceReducer() are deprecated, so I'm not sure where it's going.

@gaearon, is dynamic reducer mutation eventually going to be supported for applications apart from hot reloading? @janmarek is not the first to request this.

from redux-form.

janmarek avatar janmarek commented on May 19, 2024

You don't need multiple reducers. Just the one you have needs to take care for multiple data instances.

from redux-form.

erikras avatar erikras commented on May 19, 2024

Sure, but redux-form, in its current state is designed to operate on a single flat object of fields. If you make that object deeper and full of other objects, both the reducer and the validation get much more complicated. I think you're right in that they could both be wrapped in some other function that handled the multiplicity and let the original reducer and validation do their one-object jobs.

This relates somewhat to #21 and #23.

from redux-form.

erikras avatar erikras commented on May 19, 2024

Wow. So the solution resulted in a surprisingly simple API. See Editing Multiple Records.

from redux-form.

janmarek avatar janmarek commented on May 19, 2024

Thank you sir :)

from redux-form.

nicogreenarry avatar nicogreenarry commented on May 19, 2024

So this all works for me - but what is the name/label of one instance of a form?

I have a page that displays multiple pieces of furniture. Each piece has an 'edit' form. They're all instances of our UpdateFurnitureForm. I'm passing a unique formKey to each one, so the forms maintain data independently. The forms work exactly as intended. (Thanks for all the helpful advice above!)

Now I'd like to programmatically change the value of one of the form fields. I already have that working on another page, on a form that is a unique form (i.e., not an instance of a set of duplicate forms). I used instructions from this comment to get that working properly. See my comment in that thread for my working code.

So for the instance of one of the multiple forms, what label should I use? The formKey values I'm passing are furniture names, for example 'couch'. I've unsuccessfully tried these:

  • 'UpdateFurnitureForm'
  • 'UpdateFurnitureForm.couch'
  • 'UpdateFurnitureForm["couch"]'
  • 'UpdateFurnitureForm[couch]'
  • 'couch'

from redux-form.

steakchaser avatar steakchaser commented on May 19, 2024

Here's the reference to the multiple records example in the v5.x docs. Anyone know how / if to support this in v6?

from redux-form.

jrutter avatar jrutter commented on May 19, 2024

Hi @erikras - Im trying to setup dynamic form names, do I need to setup the formName in any special manner if Im using the code from above?

<MyRecord form={record[${record.id}]}/>`

const form = reduxForm({
  form: props.form
  // validate
});

Do I need to map props?

from redux-form.

brianium avatar brianium commented on May 19, 2024

How would this work with formValueSelector since it requires the name to match?

from redux-form.

cashkows-jason avatar cashkows-jason commented on May 19, 2024

Hi @brianium did you find a solution to this as I have the same problem?

from redux-form.

jaspersorrio avatar jaspersorrio commented on May 19, 2024

Hey guys may I ask where is this documented in v6?

I tried modeling after http://redux-form.com/5.3.3/#/examples/multirecord?_k=kcy5ns and found out that version 6 doesn't require a fields option as mentioned in this SO post http://stackoverflow.com/a/37464048/2619107.

from redux-form.

ihorml avatar ihorml commented on May 19, 2024

@erikras please help, how can we use your solution with formValueSelector ?

from redux-form.

erikras avatar erikras commented on May 19, 2024

@ihorml Is your question how to know what the form name is? Seems like you could pass ownProps of true to your connect() call to know the form name.

If that is not your question, please restate it.

from redux-form.

ihorml avatar ihorml commented on May 19, 2024

@erikras I want to use multiple forms like selectingFormValues on the same page. I'm going to pass form name using props like this:

forms.map((form) => {
  <SelectingFormValuesForm form={form.id} />
  <SelectingFormValuesForm form={form.id} />
})

But how should I pass form name to this line of your example:
const selector = formValueSelector('selectingFormValues') // <-- same as form name

If I don't know the form name?

The problem is I should have the few same forms on the same page and I should get their values on any update (not on submit).

I see you have values:Object on Instance API section and I'm trying to get form values using this.props.values but it's undefined.

from redux-form.

StevenXL avatar StevenXL commented on May 19, 2024

@anhtran1906 that worked seamlessly for me too. Thanks for the link.

from redux-form.

SidecarMaster avatar SidecarMaster commented on May 19, 2024

It's a somewhat more complicated problem than issue #28. I want to have multiple forms in one component. In the parent component, I use form={...} and initialVlaues={...} to pass in initial values for each form. It works as the solutions in the above posts suggested.

However, this works only if I do not connect the child component to redux store. For example, the code below works:

//in the parent component, render the child component
<CommentModal commentId={comment.id} form={`EditCommentForm_${comment.id}`} initialValues={comment}/>

//In the child component file, export the child component. mapStateToProps is null.
...
export default connect(
  // mapStateToProps
  null,
  // mapDispatchToProps
  { addComment, editComment, openModal, closeModal }
)(reduxForm({
    validate,
    enableReinitialize: true,
  })(CommentModal)
);

However, if I am trying to connect the component to redux store, like below:

export default connect(
  // mapStateToProps
  ({modalState})=>({modalState}),
  // mapDispatchToProps
  { addComment, editComment, openModal, closeModal }
)(reduxForm({
    validate,
    enableReinitialize: true,
  })(CommentModal)
);

It stops working. The initial values for all forms will be the initial values of the last form. I tried using ownProps, without luck:

function mapStateToProps({modalState}, ownProps ){
  console.log(ownProps)
  return {
    modalState,
    initialValues: ownProps.initialValues
  }
}

Can anyone suggest what the problem is, or a solution?

from redux-form.

cantuket avatar cantuket commented on May 19, 2024

@willshu2049

2 things that may help you...

Bug In redux Form (I think?)
You need to add a random string to the reduxForm() 'form' parameter in the options to prevent this error...

Warning: Failed prop type: The prop `form` is marked as required in 'Form(EditListing)', but its value is 'undefined'.

which appears to be a bug, but not sure if anyone else is experiencing this (redufx-form v7.0.4) Any thoughts @erikras? Solution hack...

reduxFrom({
     form:'random string here',
     validate,
    enableReinitialize: true,
}) 

Dynamic generated fields
I can't tell if this pertains to you, but I'm generating my fields dynamically from the same objects that I'm setting my initialValues. To do this I set set the initialValues={item} in the decorator component (your <CommentModal>) and as I map over these I pass down the same object to the child component to generate my fields item={item} then access it with ownProps within that child...

In Parent (EditListing.js)

return _.map(this.props.listing.listing.items, item => {
          return (
            <ItemInfo form={`editItemInfo_${item._id}`} initialValues={item} key={item._id} item={item} /> 
          );
      });

In Child (ItemInfo.js)

function mapStateToProps(state, ownProps) {
  console.log(ownProps);
  return {  
    theItem:ownProps.item
  };
}

I posted a more detailed description in Stackoverflow....
https://stackoverflow.com/questions/46182829/redux-form-form-and-initialvalues-properties-not-recognized-with-m/46203814#46203814

And here is my complete implementation...

Parent (EditListing.js)

import _ from 'lodash';
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { reduxForm } from 'redux-form';
import ListingInfo from './ListingInfo';
import ItemInfo from './items/ItemInfo';
import AddItem from './items/AddItem';
import * as actions from '../../actions';
import {Col, Row} from 'react-grid-system';

class EditListing extends Component {

  componentDidMount () {  
      const listingId = this.props.match.params.listingId;
      this.props.fetchSingleListing(listingId);
  }

  renderItemForms() {
    if (this.props.listing.listing !== undefined) {
      return _.map(this.props.listing.listing.items, item => {
          return (
            <ItemInfo form={`editItemInfo_${item._id}`} initialValues={item} key={item._id} item={item} /> 
          );
      });
    }
  }

  render() {
    return (
      <div>
        <Row>
          <Col md={6}>
            <ListingInfo/>
          </Col>
          <Col md={6}>  
            <AddItem/>
          </Col>
        </Row>
          <Row>
            <Col md={12}>
              <h3>Current Items</h3>
              <div className="row">
              {this.renderItemForms()}
             </div>
            </Col>
          </Row>
      </div>
    );
  }
}

function mapStateToProps({listing}) {
  return {listing};
}

EditListing = reduxForm({
  form: 'none',
  fields: ["text"],
  enableReinitialize: true,
})(EditListing)

EditListing = connect(mapStateToProps,actions)(EditListing)

export default EditListing

Child (ItemInfo.js)

import _ from 'lodash';
import React, { Component } from 'react';
import { reduxForm, Field } from 'redux-form';
import { connect } from 'react-redux';
import * as actions from '../../../actions';
import {Col} from 'react-grid-system';
import RaisedButton from 'material-ui/RaisedButton';


class ItemInfo extends Component {

  renderSingleItem(item){
    let theItem =  _.map(_.omit(this.props.theItem, '_id'), (value,field) => {
        return (
          <div key={field}>
            <label>{field}</label>
            <Field component="input" type="text" name={field} style={{ marginBottom: '5px' }} />
            <div className="red-text" style={{ marginBottom: '20px' }}>
            </div>
          </div>
        );
      });
    return theItem || <div></div>;
  }

  render() {      
    return (
        <Col key={this.props.theItem._id} md={3}>
          <form>
            {this.renderSingleItem(this.props.theItem)}
            <RaisedButton secondary={true} label="Remove Item"/>
            <RaisedButton primary={true} label="Update Item"/>
          </form>
        </Col>
    );
  }
}


function mapStateToProps(state, ownProps) {
  console.log(ownProps);
  return {  
    theItem:ownProps.item
  };
}

ItemInfo = reduxForm({
  fields: ["text"],
  enableReinitialize: true,
})(ItemInfo)

ItemInfo = connect(mapStateToProps,actions)(ItemInfo)

export default ItemInfo

Hope this helps

from redux-form.

malhotraashna avatar malhotraashna commented on May 19, 2024

@willshu2049 did you find some solution for using redux store with redux-form in this scenario? Facing same issue.

from redux-form.

lock avatar lock commented on May 19, 2024

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

from redux-form.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.