javascript - Reactjs - Moving a list item to another list - Stack Overflow

I'm slowly getting the knack (I think) for react. What I'm trying to do is display a list in

I'm slowly getting the knack (I think) for react. What I'm trying to do is display a list in one ponent and then make each list item (item 1, item 2, etc..) clickable so that when it is clicked, it can move back and forth between the two <ItemList /> ponents. What I have is below, I think where my problem is setting the state on the first list in the handleEvent().

class SingleItem extends React.Component {
  render() {
    let data = this.props.data;

    return (
        <li>
            <div> {data.name} </div>
        </li>
    );
  }
}

class ItemList extends React.Component {
   render() {
     let itemArr = this.props.items;

     let listItems = itemArr.map((itemObj) => {
        return <SingleItem key={itemObj.id} data={itemObj}/>;
});

    return (
        <ul onClick={props.handleEvent}>
            {listItems}
        </ul>
    );
  }
}

class App extends React.Component {
constructor(props) {
    super(props);

    this.state = {
        boxOne: {listItems},
        boxTwo:''
    };

    this.handleEvent = this.handleEvent.bind(this);
}

handleEvent() {
    this.setState({
        boxOne: this.state.boxTwo,
        boxTwo: this.state.boxOne
    });
}
render() {
    return (
        <div>
            <ItemList items={this.state.boxOne} />
            <ItemList items={this.state.boxTwo} />
        </div>
    );
  }
};

var items = [
  {name: "Item 1", id: 1},
  {name: "Item 2", id: 2},
  {name: "Item 3", id: 3},
  {name: "Item 4", id: 4},
]

ReactDOM.render(<App />, document.getElementById('root'));

I'm slowly getting the knack (I think) for react. What I'm trying to do is display a list in one ponent and then make each list item (item 1, item 2, etc..) clickable so that when it is clicked, it can move back and forth between the two <ItemList /> ponents. What I have is below, I think where my problem is setting the state on the first list in the handleEvent().

class SingleItem extends React.Component {
  render() {
    let data = this.props.data;

    return (
        <li>
            <div> {data.name} </div>
        </li>
    );
  }
}

class ItemList extends React.Component {
   render() {
     let itemArr = this.props.items;

     let listItems = itemArr.map((itemObj) => {
        return <SingleItem key={itemObj.id} data={itemObj}/>;
});

    return (
        <ul onClick={props.handleEvent}>
            {listItems}
        </ul>
    );
  }
}

class App extends React.Component {
constructor(props) {
    super(props);

    this.state = {
        boxOne: {listItems},
        boxTwo:''
    };

    this.handleEvent = this.handleEvent.bind(this);
}

handleEvent() {
    this.setState({
        boxOne: this.state.boxTwo,
        boxTwo: this.state.boxOne
    });
}
render() {
    return (
        <div>
            <ItemList items={this.state.boxOne} />
            <ItemList items={this.state.boxTwo} />
        </div>
    );
  }
};

var items = [
  {name: "Item 1", id: 1},
  {name: "Item 2", id: 2},
  {name: "Item 3", id: 3},
  {name: "Item 4", id: 4},
]

ReactDOM.render(<App />, document.getElementById('root'));
Share Improve this question asked Jun 29, 2017 at 23:41 Bobby TablesBobby Tables 1634 silver badges18 bronze badges 10
  • I see you have items array at the bottom, what is listItems in the App ponent? – FuriousD Commented Jun 29, 2017 at 23:58
  • There are several problems with you code, it's also not very clear what you are trying to do. Please describe exactly what you expect and what failed. – webdeb Commented Jun 29, 2017 at 23:59
  • What you are trying to achieve is relatively straight forward, however yes, I agree with @webdeb, there are some problems with your code. Can you please set up a fiddle – FuriousD Commented Jun 30, 2017 at 0:00
  • 1 For example this line cannot work boxOne: {listItems}, – webdeb Commented Jun 30, 2017 at 0:00
  • @FuriousD thank you for your responses, setting up a fiddle now – Bobby Tables Commented Jun 30, 2017 at 0:05
 |  Show 5 more ments

1 Answer 1

Reset to default 3

This is how it could be done..

So, I am passing the whole items array to all ItemLists, but I am also passing the state, which is just an array with ids of the included items in that list, check out the logic below and try to understand, it's easy actually..

class SingleItem extends React.Component {
  render() {
    let data = this.props.data;

    return (
        <li onClick={this.props.onClick}>
            <div> {data.name} </div>
        </li>
    );
  }
}

class ItemList extends React.Component {
   render() {
     let itemArr = this.props.allItems;
     let myItems = this.props.items;
     let handleEvent = this.props.handleEvent;

     let listItems = itemArr.map((itemObj) => {
        if (!myItems.includes(itemObj.id)) return null;

        return <SingleItem 
          key={itemObj.id}
          data={itemObj}
          onClick={() => handleEvent(itemObj.id)}
        />;
     });

     return (
        <ul>
            {listItems}
        </ul>
     );
   }
}

class App extends React.Component {
constructor(props) {
    super(props);

    this.state = {
        boxOne: props.items.map(item => item.id), // init the boxes with itemIds
        boxTwo: []
    };

    this.handleEvent = this.handleEvent.bind(this);
}

handleEvent(itemId) {
    const isInBoxOne = this.state.boxOne.includes(itemId);

    // Heres the magic, if the item is in the first Box, filter it out,
    // and put into the second, otherwise the other way around..
    this.setState({
        boxOne: isInBoxOne
          ? this.state.boxOne.filter(i => i !== itemId)
          : [ ...this.state.boxOne, itemId ]
        boxTwo: isInBoxOne
          ? [ ...this.state.boxTwo, itemId ]
          : this.state.boxTwo.filter(i => i !== itemId)
    });
}
render() {
    return (
        <div>
            <ItemList handleEvent={this.handleEvent} items={this.state.boxOne} allItems={this.props.items} />
            <ItemList handleEvent={this.handleEvent} items={this.state.boxTwo} allItems={this.props.items} />
        </div>
    );
  }
};

var items = [
  {name: "Item 1", id: 1},
  {name: "Item 2", id: 2},
  {name: "Item 3", id: 3},
  {name: "Item 4", id: 4},
]

ReactDOM.render(
  // Pass the initial items to your App
  <App items={items} />,
  document.getElementById('root')
);

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745634705a4637320.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信