So I am having a few problems with this, but first let me outline what I am trying to do.
When the user first logs in , it takes them to /home
which has a list of projects. Clicking on one of the projects will take them to /project/84
if 84
is the number of that project. When they are routed to that URL there is a <select>
with a list of projects (that were also listed on /home
).
This is what should happen:
1) The <select>
should have a value
equal to the name of the project selected. For example, if project 84
is called Project 84
, it should already be displayed in the <select>
even if there are 20 other other projects before and after it.
2) When the user selects a new <option>
in <select>
, it should automatically send a GET
to the server to retrieve the information of the project they selected.
So here is what I have so far:
import _ from 'lodash';
import React, { Component } from 'react';
import { connect } from 'react-redux';
class SelectProject extends Component {
getProject() {
// console.log('Working');
this.setState({
value: event.target.value
});
}
renderCurrentProjectName() {
const { project_list } = this.props;
if (!Project_list) {
return <div>Loading...</div>;
}
return _(this.props.Project_list)
.filter(c => c.project_id == this.props.Project_id)
.map('project')
.value();
}
renderProjectSelect() {
return _.map(this.props.project_list, s => {
return (
<option key={s.project_id}>{s.project}</option>
);
});
}
render() {
return (
<div className='panel panel-default'>
<div className='panel-heading'>
<h4><strong>{this.renderCurrentProjectName()}</strong></h4>
</div>
<div className='panel-body'>
<select className='form-control' onChange={this.getProject()} value={this.renderCurrentProjectName()}>
{this.renderProjectSelect()}
</select>
</div>
</div>
);
}
}
function mapStateToProps(state) {
return {
project_id: state.documents.project_id,
project_list: state.documents.project_list
}
}
export default connect(mapStateToProps, null)(SelectProject);
This just generates 1000 errors saying: Cannot update during an existing state transition (such as within 'render' or another component's constructor). Render methods should be a pure function of props and state; constructor side-effects are an anti-pattern, but can be moved to 'componentWillMount'.
This is caused by the this.setState({ value: even.target.value })
so when I remove it I just get: Warning: Failed form propType: You provided a 'value' prop to a form field without an 'onChange' handler. This will render a read-only field. If the field should be mutable use 'defaultValue'. Otherwise, set either 'onChange' or 'readOnly'. Check the render method of 'SelectProduct'.
This does accomplish 1)
though by selecting the name of the project in the <select>
; however, you can't select anything else (haven't even gotten as sending the GET
).
defaultValue
doesn't seem to do anything, at least it doesn't select the correct <option>
.
Also have done the following which resulted in the same errors and behavior (i.e. it selects the correct <option>
, but won't let you select anything else):
...
class SelectProject extends Component {
constructor(props) {
super(props);
this.state = {
value: this.renderCurrentProductName()
};
}
getProject() {
// console.log('Working');
this.setState({
value: event.target.value
});
}
...
<select className='form-control' onChange={this.getProject()} value={this.state.value}>
{this.renderProjectSelect()}
</select>
...
These are some of the SO questions I have been referencing.
OnChange event using React JS for drop down
ReactJS: Select with default value from props without onChange event?