Reputation: 11
Below is my code
jobClickedHandler = (event, index) => {
return (
<EditJobScheduler
open={this.state.editModalActive}
onClose={this.closeEditModal}
scheduleJobHandler={this.scheduleJobHandler}
inputHandler={this.inputHandler}
jobInfo={this.state.jobData[index]}
/>
)
this.setState( { editModalActive: true });
}
The component above receives it's parameters from the click event.
I call this inside of my render method, like so.
{this.state.editModalActive && this.jobClickedHandler() }
When I call this.jobClickedHandler method as a function, my component errors out that is expecting that data (I cannot access the properties because it is receiving undefined)
Below is the component that is expecting the prop
class EditJobScheduler extends Component {
constructor(props) {
super(props);
this.state = { modalActive: false, todayDate: moment() }
}
handleChange = (date) => {
this.setState({
todayDate: date
});
}
render() {
console.log(this.props.jobInfo)
return (
<Modal
open={this.props.open}
onClose={this.props.onClose}
>
<form className ="modalForm"onSubmit = {this.props.scheduleJobHandler}>
<h2 id = "header">Schedule a new job</h2>
{/*<span id= "exit" onClick={this.closeModal}>⊗</span>*/}
<br />
<label>Full Name of Customer</label><br />
<input name = "customerName" type = "text" value={this.props.jobInfo.jobName} onChange = {this.props.inputHandler}></input>
<br />
<br />
<label>Job Type</label>
<br />
<select name = "jobType" onChange = {this.props.inputHandler}>
<option selected value = {this.state.jobInfo}></option>
<option value = "Plumbing">Plumbing</option>
<option value = "Septic">Septic</option>
<option value = "Drain">Drain</option>
</select>
<br />
<br />
<label>Phone Number</label><br />
<input name = "phone" type = "tel" value={this.state.jobInfo.jobPhoneNumber} onChange = {this.props.inputHandler}></input>
<br />
<br />
<label>Job Address</label><br />
<input ref = "jobAddress" name="address"type = "text" value={this.props.jobInfo.jobAddress} onChange = {this.props.inputHandler}></input>
<br />
<br />
<label>Assigned Tech</label><br />
<select name = "assignedTech" onChange = {this.props.inputHandler}>
<option value = {'Select a Tech'}></option>
<option value = "Kaleb">Kaleb</option>
<option value = "Andrew">Andrew</option>
<option value = "John">John</option>
</select><br />
<br />
<label>Date of service</label><br />
<DatePicker
selected={this.props.jobInfo.jobDate}
onChange={this.handleChange}
/>
<div className = "submit">
<button type = "submit" onClick = {this.props.scheduleJobHandler} className = "btn btn-success">Schedule</button>
</div>
</form>
</Modal>
)
}
}
I'm just trying to fill the input's with the data from state. Any ideas as to why undefined is being passed through my prop instead of the data?
Upvotes: 0
Views: 104
Reputation: 8418
I think you're trying to join handler and renderer into one method.
It doesn't make sense - handler changes state which will force new render - event if it would work in first pass - next would overwrite it but also call setState and so on...
Just use it separately:
jobClickedHandler = (event, index) => {
this.setState( { editModalActive: true });
}
renderEditModal = () => {
return (
<EditJobScheduler
open={this.state.editModalActive}
onClose={this.closeEditModal}
scheduleJobHandler={this.scheduleJobHandler}
inputHandler={this.inputHandler}
jobInfo={this.state.jobData[index]}
/>
)
}
{this.state.editModalActive && this.renderEditModal() }
I would also decompose content/functional parts to separate components to avoid rerendering of all elements on each state change.
Upvotes: 1
Reputation: 81
Typically the issue when something like this ends up as undefined is that the "this" isn't bound to a specific object. For classes that have methods that use "this", especially using react, I would recommend binding them in the constructor. For example:
class EditJobScheduler extends Component {
constructor(props) {
super(props);
this.state = { modalActive: false, todayDate: moment() };
this.handleChange = this.handleChange.bind(this);
}
handleChange = (date) => {
this.setState({
todayDate: date
});
}
Something like this binds the method to each instance rather than to the class itself. I hope this helps.
Upvotes: 0