Reputation: 1274
I'm making an application using React.js. I have a list of items. A list of item is editable.
I want to add a title element next to a list of items and a height of title element should be changed as the number of item is increased or decreased.
If the number of item is decreased to 3, the height of title element(Advice & FAQ) should be shorten. If it is increased to 5, the height should be widened.
How can I achieve this functionality? I tried to use inline styling but I failed..
<div className="titleElement" style={height: this.state.questionItem.length * 20px }></div>
index.js
export default class List extends React.Component {
constructor(props){
super(props);
this.state={
questionItem
};
}
createItem(item){
this.state.questionItem.unshift({
item : item,
});
this.setState({
questionItem : this.state.questionItem
});
}
findItem(item) {
return this.state.questionItem.filter((element) => element.item === item)[0];
}
toggleComplete(item){
let selectedItem = this.findItem(item);
selectedItem.completed = !selectedItem.completed;
this.setState({ questionItem : this.state.questionItem });
}
saveItem(oldItem, newItem) {
let selectedItem = this.findItem(oldItem);
selectedItem.item = newItem;
this.setState({ questionItem : this.state.questionItem });
console.log(this.state.questionItem)
}
deleteItem(item) {
let index = this.state.questionItem.map(element => element.item).indexOf(item);
this.state.questionItem.splice(index, 1);
this.setState({ questionItem : this.state.questionItem });
}
render() {
return (
<div className="list">
<div className="titleElement" style={height: this.state.questionItem.length * 20px }></div>
<QuestionList questionItem={this.state.questionItem} deleteItem={this.deleteItem.bind(this)} saveItem={this.saveItem.bind(this)} toggleComplete={this.toggleComplete.bind(this)} />
<CreateItem questionItem={this.state.questionItem} createItem={this.createItem.bind(this)} />
</div>);
}
}
Upvotes: 2
Views: 8600
Reputation: 4811
I think you're doing too much work manually. You should look at flexbox and have CSS automatically handle the height resizing for you. The end result would be something like (have not tested this, just giving you a conceptual idea):
render() {
return (
<div className="list" style={{"display": "flex";}}>
<div className="titleElement" style={{"flex": 1}}></div>
<div style={{"flex": 5; "display": "flex"; "flex-direction": "column"}}>
<QuestionList questionItem={this.state.questionItem} deleteItem={this.deleteItem.bind(this)} saveItem={this.saveItem.bind(this)} toggleComplete={this.toggleComplete.bind(this)} />
<CreateItem questionItem={this.state.questionItem} createItem={this.createItem.bind(this)} />
</div>
</div>);
}
The outer div
has display: flex
set to enable flex box, then you can play with the flex: 1
and flex: 5
settings in the children divs
to get the widths correct.
I would then add the wrapping div
around QuestionList
and CreateItem
so that you can make those appear vertically / in columns (with the display: flex
and flex-direction: column
styles).
Upvotes: 6
Reputation: 470
I agree with user1370384 that you are doing a lot of work manually, and here is a post that discusses the correct way to do inline styles as objects Reactjs - setting inline styles correctly.
However, if you wanted to do your original approach, perhaps backticks aka ES6 Template Literals may be a solution like below. (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals)
render() {
return (
<div className="list">
<div className="titleElement" style={{'height': `${this.state.questionItem.length * 20}px` }}>
</div>
<QuestionList questionItem={this.state.questionItem} deleteItem={this.deleteItem.bind(this)} saveItem={this.saveItem.bind(this)} toggleComplete={this.toggleComplete.bind(this)} />
<CreateItem questionItem={this.state.questionItem} createItem={this.createItem.bind(this)} />
</div>
);
}
Upvotes: 2