如何使用React.js重用具有添加/删除功能的列表组件用于其他列表

时间:2017-09-22 09:29:40

标签: reactjs

我有一个重用组件的问题,这些组件在React中添加/删除/编辑/保存功能。

列表的功能基本上就像待办事项列表。但是,我想制作几个单独的类别列表。每个类别都应存储数据以制作数据图表。 (我将其存储为this.state.questionItem.length

enter image description here

我列出了橙色标题的清单。我想制作一个蓝色和红色的列表。

const questionItem = [ { item : 'Lorem ipsum dolor sit amet, 
consectetur adipiscing elit, sed do eiusmod tempor?', id : 1
}, 
{ item : 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, 
sed do eiusmod tempor?', id : 2
}, 
{ item : 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, 
sed do eiusmod tempor?', id : 3
},
 { item : 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, 
sed do eiusmod tempor?', id : 4
}
]

class CreateItem extends React.Component {

    constructor(props){
    super(props);
    this.state={
        modal : false,
        open: false
    };
    this.toggle = this.toggle.bind(this);
    }

    toggle() {
    this.setState({
    modal: !this.state.modal
    });
    }

 handleOpen = () => {
 this.setState({open: true});
 };

 handleClose = () => {
 this.setState({open: false});
 };


 handleCreate(e) {
    e.preventDefault();

    if(!this.refs.newItemInput.value) {
        alert('enter a question');
        return;
    } else if (this.props.questionItem.map(element=> element.item).indexOf(this.refs.newItemInput.value) != -1
    ) {
        alert('This question already exist');
        this.refs.newItemInput.value = '';
        return;
    }
    this.props.createItem(this.refs.newItemInput.value);
    this.refs.newItemInput.value = '';
}

render() {
    return(
         <div className="createNew">
         <p> Add new ? </p>
        <div className="addSample" onClick={this.handleOpen}><img src={Add} className="add" alt="add"/></div>
        <Dialog
        title="Add a new question"
        modal={false}
        open={this.state.open}
        onRequestClose={this.handleClose}
        >
        <form onSubmit={this.handleCreate.bind(this)}   >
        <input type="text" placeholder="New Question" ref="newItemInput" />
        <button onClick={this.handleClose}>Submit</button>
        </form>
        </Dialog>
        </div>
        );
}
}


class QuestionItem extends React.Component {

    constructor(props){
     super(props);
     this.state ={
      editing: false,
      open: false,
      popOver:false
    };
    this.toggle = this.toggle.bind(this);
    }

  handleOpen = () => {
  this.setState({open: true});
  };

  handleClose = () => {
  this.setState({open: false});
  };

  handleTouchTap = (event) => {
  // This prevents ghost click.
  event.preventDefault();

  this.setState({
  popOver: true,
  anchorEl: event.currentTarget,
 });
 };

  handleRequestClose = () => {
  this.setState({
  popOver: false,
  });
  };


  toggle() {
  this.setState({
  modal: !this.state.modal
  });
  console.log(this.state.modal)
  }


  onEditClick(){
    this.setState({
        editing:true
    })
  }

  onCancelClick(){
    this.setState({
        editing: false
    })
  }

  onSaveClick(e){
    e.preventDefault();
    this.props.saveItem(this.props.item, this.refs.editInput.value);
    this.setState({ editing: false });
   }

  renderName() {
     const itemStyle = {
        'text-decoration' : this.props.completed ? 'line-through' : 'none',
         cursor : 'pointer'
    };

    if(this.state.editing) {
        return (
            <form onSubmit={this.onSaveClick.bind(this)}>
            <input type="text" ref="editInput" defaultValue={this.props.item} />
            </form>
            );
      }

     return(
    <span style={itemStyle}>
    {this.props.id} {this.props.item}</span>);
   }

  renderButtons() {
    if(this.state.editing) {
        return (
            <span>
            <div className="saveSample" onClick={this.onSaveClick.bind(this)}><img src={Check} className="edit" alt="edit"/></div>
            <div className="cancelSample" onClick={this.onCancelClick.bind(this)}><img src={Fail} className="edit" alt="edit"/></div>
            </span>
            );
    }
    return(
    <span>
            <div className="editSample" onClick={this.onEditClick.bind(this)} onClick={this.handleOpen}><img src={Edit} className="edit" alt="edit"/></div>
            <div className="trashbinSample" onClick={this.props.deleteItem.bind(this, this.props.item)}><img src={Trashbin} className="trashbin" alt="Trashbin"/></div>
            <div className="dotmenuquestionSample"><img src={Dotmenu} alt="Dotmenu" className="Dotmenu" onClick={this.handleTouchTap} /> </div>
    </span>
    )
}
render() {
 return(
 <div className="questionItem">
 <span className="name">
 {this.renderName()}
 </span>
 <span className="actions">
 {this.renderButtons()}
 </span>
    <Dialog
      title="Edit a question"
      modal={false}
      open={this.state.open}
      onRequestClose={this.handleClose}
    >
      <form onSubmit={this.onSaveClick.bind(this)}>
            <input type="text" ref="editInput" defaultValue={this.props.item} />
      <button className="modalButton" onClick={this.handleClose}>Submit</button>
       </form>
    </Dialog>

     <Popover
      zDepth={5}
      open={this.state.popOver}
      anchorEl={this.state.anchorEl}
      anchorOrigin={{horizontal: 'right', vertical: 'bottom'}}
      targetOrigin={{horizontal: 'left', vertical: 'top'}}
      onRequestClose={this.handleRequestClose}
    >

     <Menu>
        <MenuItem primaryText="Item1" />
        <MenuItem primaryText="Item2" />
        <MenuItem primaryText="Item3" />
        <MenuItem primaryText="Item4" />
      </Menu>
    </Popover>


</div>
);
}
}

class QuestionList extends React.Component {
renderItems() {
    return this.props.questionItem.map((item, index) => <QuestionItem 
    key={index} {...item} {...this.props} />);
}
render() {
return (
<div className="item-list">
 {this.renderItems()}
</div>
);
}
}

export default class List extends React.Component {

    constructor(props){
    super(props);
    this.state={
        questionItem,
        pieData : [{label: "question1", value: 4}, {label: "question2", 
        value: 10}, {label: "question3", value: 25 },{label: 
        "question4", value: 5 },{label: "question5", value: 12 }]
    }
    }

    createItem(item){
    this.state.questionItem.unshift({
        item : item,
    });

    let length1 = questionItem.length;

    var array = [
    {label : "question1" ,value : length1 },
    {label : "question2" , value : length1 },
    {label : "question3" , value : length1 },
    {label : "question4" , value : length1 }, 
    {label : "question5" , value : length1 } ]

    this.setState({
        questionItem : this.state.questionItem,
        pieData : array
    });
    }

    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;

    let length1 = questionItem.length;

    var array = [
    {label : "question1" ,value : length1 },
    {label : "question2" , value : length1 },
    {label : "question3" , value : length1 },
    {label : "question4" , value : length1 }, 
    {label : "question5" , value : length1 } ]
     this.setState({ questionItem : this.state.questionItem,
                     pieData : array });
      }

     deleteItem(item) {
    let index = this.state.questionItem.map(element => 
    element.item).indexOf(item);
    this.state.questionItem.splice(index, 1);

    let length1 = questionItem.length;

    var array = [
    {label : "question1" ,value : length1 },
    {label : "question2" , value : length1 },
    {label : "question3" , value : length1 },
    {label : "question4" , value : length1 }, 
    {label : "question5" , value : length1 } ]

    this.setState({ questionItem : this.state.questionItem,
                      pieData : array
                 });
    }

render() {
    const { questionItem } = this.state
    return (
    <div>
    <DataChart data = { this.state.pieData} /> 
    <div className="list" style={{"display" : "flex"}}>
    <div className="titleElement" style={{"flex": "1", "backgroundColor" : "orange"}}>Advice + FAQ </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>
     </div>);
}
}

 class DataChart extends React.Component {
 render(){
 var PieChart = rd3.PieChart
 var pieData = [{label: "question1", value: 4}, {label: "question2", value: 10}, {label: "question3", value: 25 },{label: "question4", value: 5 },{label: "question5", value: 12 }];

 return  (
  <PieChart
  data={this.props.data}
  width={450}
  height={400} 
  radius={110}
  innerRadius={20}
  sectorBorderColor="white"
  title="Pie Chart" />
)}
}

1 个答案:

答案 0 :(得分:0)

听起来您可以将prop向下传递给List,并使用prop来设置组件的样式:

render() {
    const { questionItem } = this.state
    // this is new
    const titleStyle = {
       "flex": "1", 
       "backgroundColor" : this.props.titleColor // or what ever you want to call it
    }
    return (
    <div>
    <DataChart data = { this.state.pieData} /> 
    <div className="list" style={{"display" : "flex"}}>
    <div className="titleElement" style={ titleStyle }>Advice + FAQ </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>
     </div>);
}

然后像

一样使用它
<List titleColor="orange" { ...maybeOtherPropsHere }>

或者,如果您需要执行一些逻辑来决定颜色,您可以将其分解为函数并调用它以获得所需的颜色。

<List titleColor={ getHeaderColor(args, to, help, decide) } { ...maybeOtherPropsHere }>