I have a grandparent component that renders a card parent component by mapping over an array. Those parent cards have form children. The call to handle the submit function of the forms is in the grandparent. How can I know from which parent the form is coming?
I read this SO explainer about the difference between props and state several times, and I think it is possible that I somehow need to get to state instead of props, but when I console.log(this.state)
in the handleSubmit
function, it is null.
In my contrived example, I have a set of monkeys and a set of cupcakes. The cupcakes include a reference to the monkeys (stored in mongodb and my state), so that each cupcake belongs to one monkey. In order to create a new cupcake, I need to know which monkey it goes with.
I've tried several things, including passing the monkey in the form, adding a hidden field with the monkey (which seems very hackish to begin with and did not work). When I console.log(this.props)
in the child form render()
method, it shows that monkey
is part of the props. However, monkey does not come through in the this.props
that is passed through {handleSubmit}
. I simply do not understand.
monkeys.js - the grandparent (the monkey cards are the parents)
What I really want is for the handleCupcakeSubmit
to include information about the monkey, so I can create a new cupcake for that monkey.
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import MonkeysCupcakes from './monkeyscupcakes';
import AddCupcakeForm from './add_cupcake_form';
export default class Monkeys extends Component {
constructor(props) {
super(props);
this.handleCupcakeSubmit = this.handleCupcakeSubmit.bind(this);
}
handleCupcakeSubmit({monkey, color }) {
console.log("trying to submit a cupcake")
console.log(this.state)
console.log('handleSubmitCupcake with', monkey, color);
// const userid = this.props.monkey.user;
// const mid = this.props.monkey._id;
// Eventually, I want to be able to have the userid and monkeyid - both of which are in the monkey props
//this.props.createCupcake({ userid, mid, color });
}
renderMonkeyCupcakes(mid) {
if (
this.props.cupcakes !== undefined &&
this.props.cupcakes.length > 0
) {
console.log("Monkeys is trying to render it's cupcakes");
const mc = this.props.cupcakes.filter(
cupcake => cupcake.monkeyid === mid
);
return <MonkeysCupcakes cupcakes={mc} />;
} else {
console.log('Monkeys has no cupcakes');
}
}
render() {
return (
<div>
{this.props.monkeys.map((monkey, i) => (
<div key={i} className="card blue-grey darken-1">
<div className="card-content white-text">
<span className="card-title">{monkey.name}</span>
<p>I am a monkey card</p>
<AddCupcakeForm monkey={monkey}
onSubmit={this.handleCupcakeSubmit}
/>
</div>
{this.renderMonkeyCupcakes(monkey._id)}
</div>
))}
</div>
);
}
}
Monkeys.propTypes = {
monkeys: PropTypes.array,
cupcakes: PropTypes.array
};
add_cupcake_form.js the child
import React, { Component } from 'react';
import { reduxForm, Field } from 'redux-form';
import { connect } from 'react-redux';
import renderTextField from '../helpers/textfield';
import { createCupcake } from '../../actions';
class AddCupcakeForm extends Component {
render() {
const { handleSubmit } = this.props; // no monkey
console.log("add cupcake form props", this.props); // this.props.monkey exists
return (
<div className="section">
<form onSubmit={handleSubmit}>
<Field
label="Color"
name="color"
placeholder="Purple"
component={renderTextField}
type="text"
/>
<button className="btn-large" type="submit">
Add Cupcake
<i className="material-icons right">done</i>
</button>
</form>
</div>
);
}
}
const validate = values => {
const errors = {};
if (!values.color) {
errors.color = 'Please enter cupcake color';
}
return errors;
};
export default reduxForm({
form: 'addcupcake',
validate
})(connect(null, { createCupcake })(AddCupcakeForm));
My project is on github, the branch with this issue is called connectcuptomonkeys which should be right here