-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[V6RC4] FieldArray + Dynamic select options #1484
Comments
I think you could use option 1. In your import range from 'lodash/range'
const selector = formValueSelector('fooForm')
const mapStateToProps = (state) => {
const fieldArrayRows = selector(state, 'fieldArrayRows')
const countryNameFields = fieldArrayRows && range(fieldArrayRows).map((row) =>
`fieldArrayRows[${row}].countryName`)
return {
countryNames: selector(state, countNameFields)
}
} Note: I haven't tested this code, it's just a gist. Should give you an idea though. |
@clayne11 Thanks for the idea, I'll definitely try that to check if it works. It's still not perfect IMO because it means whenever there is a change (be it a change of value on the first fields, or an add/remove of rows), it will re render the whole form (as per formSelector documentation), whereas my need is to re-render only the second dropdown on change of the first. |
I just realized the gist I gave you was silly. You can just map over the const selector = formValueSelector('fooForm')
const mapStateToProps = (state) => {
const fieldArrayRows = selector(state, 'fieldArrayRows')
const countryNames = fieldArrayRows && fieldArrayRows.map(({countryName}) =>
countryName)
return {
countryNames
}
} As for re-rendering, that's such a minute issue you on't even need to be concerned about it. The issue with extra renders is more for text fields. If you have the entire form re-rendering every time you enter a letter in a text field you'll end up with brutal lag on a big form. When you're looking at a dropdown like you're referring to you don't have the kind of rapid-fire input you get a from a text field and a single extra render won't cause any noticeable performance problems. If you're still not happy with that performance you can add the |
@clayne11 don't worry about the range stuff, I had already changed this part :D |
Please excuse my highjacking of this thread, but I have the same issue and tried to implement what you discussed. Apparently I'm missing something. Here's what I got so far (Shortened): {
"id": 1,
"sequences": [
{
"sequence": 1,
"command": "dothis",
"data": "blablu"
},
{
"sequence": 2,
"command": "dothat",
"data": "yaddayadda"
},
{
"sequence": 3,
"command": "dontlookback",
"data": "1234567"
}
]
} class Routing extends Component {
constructor(props) {
super(props);
}
render() {
const { sequences, sequenceCommands } = this.props
console.log(`sequenceCommands: ${sequenceCommands}`)
return (
<div>
{sequenceCommands && <div>
<span>commandValue: {sequenceCommands[0].command}</span>
</div>}
<FieldArray name="sequences"
component = { renderSequences }
/>
</div>
);
}
};
Routing = reduxForm({
form: 'routingForm',
enableReinitialize: true
}
)(Routing)
Routing = connect(
state => ({
initialValues: {sequences:state.route.sequences}
})
)(Routing)
const selector = formValueSelector("routingForm")
const mapStateToProps = (store, state) => {
const sequenceFormArray = selector(state, 'sequences')
const sequenceCommands = sequenceFormArray && sequenceFormArray.map(
({sequence}) => sequence && sequence.command
)
// maps store.route to this.props
return {
sequences: store.route,
sequenceCommands: sequenceCommands
}
}
export default connect(mapStateToProps)(Routing); Shouldn't |
Hmm, I got it working, but not in mapStateToProps. Instead I just went back to the component-generator and declared the selector there: Routing = reduxForm({
form: 'routingForm',
enableReinitialize: true
}
)(Routing)
const selector = formValueSelector("routingForm")
Routing = connect(
state => ({
initialValues: {sequences:state.route.sequences},
sequenceFormArray: selector(state, "sequences"),
})
)(Routing)
const mapStateToProps = function(store) {
// maps store.route to this.props
return store.route
}
export default connect(mapStateToProps)(Routing); and check and use its content on the render like this: {sequenceFormArray && <div>
<span>sequenceFormArray: {sequenceFormArray[0].command}</span>
</div>} Not the most elegant way I guess, but at least it's working now. |
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. |
Hi,
My scenario is as follows: I want a dynamic number of rows where each row contains 2
<select>
fields (say, one with a country and one with a city).I have the map
[{"France": ["Paris", "Lyon"]},{"Belgium": ["Brussels", "Gent"]}]
available as props of my form.I can add or remove a row at will.
Example:
Of course I don't want to be able to select
|France|Brussels
, so I must make the second<select>
field of each row dynamic depending on the first.I tried the following solutions:
#1) With form selector
As there are N dynamic rows, I wrapped the rows in a FieldArray. The problem is that formValueSelector does not appear to work well with FieldArrays. The only thing that works seems to select the whole FieldArray (e.g.
selector(state, 'fieldArrayRows')
). A weird consequence is that it doesn't seem to re-render the UI (as mentioned here), maybe because the changes happen on nested elements.In particular, it is impossible to write
selector(state, 'fieldArrayRows[].countryName')
, which would be a decent solution for me.#2) With Normalizing
Unfortunately Normalizing seems to exist only to fine-tune the field value right before it is written in the state. It doesn't allow to fine-tune the display based on values.
#3) With onChange
I can add an onChange to the
country
select, but I don't see how to rerender the correspondingcity
field based on the value. AFAIU the only way to rerender is to change the state/props.Sorry for the long question/issue, I appreciate any help!
The text was updated successfully, but these errors were encountered: