Reputation: 3327
I'm new to react and trying to pick this up by following some tutorials but I am having some issues getting the dropdown list title to change based on the value that was selected in the drop down list. I'm using react bootstrap
to try to do this but am not sure how to get the title to change.
Right now, when ever the drop down is selected, I call onDropChange
function and I'm trying to set the state to the value of the dropdown that was selected so then I can use it in the title, but I can't even get that to work.
Here is my code so far:
import React, {PropTypes} from 'react';
import {connect} from 'react-redux';
import * as courseActions from '../../actions/courseActions';
import * as ReactBootstrap from 'react-bootstrap';
class CoursesPage extends React.Component {
constructor (props, context) {
super(props, context);
this.state = {
course: {title: ""},
drplist: {drpval: ""}
};
this.onTitleChange = this.onTitleChange.bind(this);
this.onClickSave = this.onClickSave.bind(this);
this.onDropChange = this.onDropChange.bind(this);
}
onTitleChange (event) {
//console.log("event: ", event)
const course = this.state.course;
// console.log("course: ", course);
course.title = event.target.value;
this.setState({course: course});
}
onClickSave () {
this.props.dispatch(courseActions.createCourse(this.state.course));
}
courseRow(course, index) {
return <div key={index}>{course.title}</div>
}
onDropChange (eventKey) {
console.log("drop change: ", eventKey);
const drplist = this.state.drplist;
drplist.drpval = eventKey;
console.log('title2:', drplist.drpval);
}
render (title) {
let data = [1,2,3,4]
const makeList = function(x) {
return <ReactBootstrap.MenuItem eventKey={x}>{x}</ReactBootstrap.MenuItem>
}
console.log("title:", title)
return (
<div>
<h1>Courses</h1>
{this.props.courses.map(this.courseRow)}
<h2>Add Course</h2>
<input
type="text"
onChange={this.onTitleChange}
value={this.state.course.title} />
<input
type="submit"
value="save"
onClick={this.onClickSave} />
<ReactBootstrap.DropdownButton title="test drop" id="bg-vertical-1" onSelect={this.onDropChange}>{data.map(makeList)}</ReactBootstrap.DropdownButton>
</div>
);
}
}
function mapStateToProps(state, ownProps) {
return {
courses: state.courses
};
}
export default connect(mapStateToProps) (CoursesPage);
-------EDIT-------
I think I'm getting some where:
I made the initial state look like this:
this.state = {
course: {title: ""},
drplist: {drpval: "Drop Down"}
};
I then changed the render part to this:
<ReactBootstrap.DropdownButton title={this.state.drplist.drpval} id="bg-vertical-1" onSelect={this.onDropChange}>{data.map(makeList)}</ReactBootstrap.DropdownButton>
but title={this.state.drplist.drpval}
doesn't seem to reflect the updated state...
Upvotes: 0
Views: 4281
Reputation: 2701
You are mutating your state. I strongly suggest you to read about immutability in React.
onTitleChange (event) {
const course = this.state.course;
this.setState({
course: {
...this.course,
title: event.target.value
}
});
}
Make sure the object spread operator plugin is enabled in your babel configuration. Otherwise, you may use Object.assign.
Upvotes: 1
Reputation: 1798
You need to set/update the state correctly. Both course
and drplist
are objects. So when an update to these objects happens, you need to "let React know" about the update, so it knows that it needs to re-render something. A "hack" would be to call this.forceUpdate()
after console.log('title2:', drplist.drpval);
.
However, the correct thing would be to update the state correctly. Instead of directly manipulating the object values, first clone the state object you want to update, and then use this.setState
to inform React about the update. So change your onDropChange
function to.
console.log("drop change: ", eventKey);
//make a shallow-copy of the drplist object
let drplist = Object.assign({}, this.state.drplist);
drplist.drpval = eventKey;
console.log('title2:', drplist.drpval);
this.setState({drplist: drplist});
A similar bug is in your onTitleChange
Upvotes: 1