Невозможно переключить отдельный элемент массива в реакции - PullRequest
0 голосов
/ 19 марта 2020

Я пытаюсь создать простое приложение со списком покупок, в котором товары добавляются вместе с кнопкой удаления и могут быть отмечены / не отмечены. Я пытаюсь переключить элемент при нажатии. Переключатель работает, но он применяет изменения ко всем элементам в массиве. Я хотел бы только переключить пункт, который нажимается. Вот код:

Приложение. js

import React, { Component } from 'react'
import Result from './Result';
import Navbar from './Navbar';
import Jumbotron from 'react-bootstrap/Navbar';
import Button from 'react-bootstrap/Button';
import Form from 'react-bootstrap/Form';
import Alert from 'react-bootstrap/Alert';
import SearchResult from './SearchResult';


export default class App extends Component {
    constructor(){
    super();
      this.state={
        addedItems:[],
        emailValue:'',
        searchValue:'',
        searchedItems:[],
        selected:false
      }
      this.handleChange=this.handleChange.bind(this);
      this.handleSubmit=this.handleSubmit.bind(this);
      this.onDelete=this.onDelete.bind(this);
      this.handleToggle=this.handleToggle.bind(this);
      this.handleSearch=this.handleSearch.bind(this);
      this.searchResult=this.searchResult.bind(this);
    }

     handleChange(e){
       this.setState({
         emailValue:e.target.value
       })
     }
     handleSubmit(e){
      e.preventDefault();
      let items_copy= this.state.addedItems;
      items_copy.push(this.state.emailValue)
      console.log("item copy"+items_copy)
      this.setState({
        addedItems:items_copy,
        emailValue:''
      })
      console.log(this.state.addedItems)
     }

     handleSearch(e){
       this.setState({
         searchValue:e.target.value
       },()=>{
         this.searchResult(this.state.searchValue)
       })  
     }

     searchResult(searchValue){
       let searchArray=[]
        this.state.addedItems.map(item=>{

          if(item.find(searchValue)){
            searchArray.push(item)
          }
        })
        this.setState({
          searchedItems:searchArray
        })
     }
     handleToggle(){
      console.log("toggled")
      console.log("selected state"+this.state.selected)
      this.setState({
        selected:!this.state.selected
      })
     }

     onDelete(id){
      let items=this.state.addedItems
      console.log("On Delete")
      console.log(items[id])
      let newArray=items.filter((i,itemNumber)=>id!==itemNumber)
      this.setState({
        addedItems:newArray
      })
     }
  render() {
    console.log("")
    return (
     <div>
          <Navbar/>
          <Jumbotron>
          <Alert variant="success">
        <Alert.Heading>Enter the things you would like to buy </Alert.Heading>
        </Alert>
        </Jumbotron>

        <Form>
          <Form.Group controlId="formBasicEmail">
            <Form.Control value={this.state.emailValue} onChange={this.handleChange}type="email" placeholder="Enter email" />
          </Form.Group>
          {(this.state.addedItems.length>0)?
          <Form.Group controlId="formBasicEmail">
            <Form.Control value={this.state.searchValue} onChange={this.handleSearch}type="text" placeholder="Search for an item..." />
          </Form.Group>:''}
          <Button onClick={this.handleSubmit}variant="primary" type="submit">
            Submit
          </Button>
        </Form>



        {(this.state.addedItems.length>0)?
        <Result item={this.state.addedItems} onDelete={this.onDelete} selected={this.state.selected}handleToggle={this.handleToggle}/>
        :<Alert variant="info">
          Your list is empty
        </Alert>
          }     
      </div>
    )
  }
}

Результат. js

import React from 'react'
import ListGroup from 'react-bootstrap/ListGroup'
import Button from 'react-bootstrap/Button'

export default function Result(props) {
    const btnStyle={
        marginTop:-7,
        float:'right'
    };

    const {item,onDelete, handleToggle, selected}=props;
    //let show=item.map(item=>item);
    console.log(item) 
    console.log(selected+"In result")
    let itemShow = item.map((item,i) =>{    
     return ( 
         <li onClick={()=>handleToggle(i)}class="list-group-item"  style={{textDecorationLine: selected?'line-through':'none',textDecorationStyle: selected?'solid':'none', border: selected?' 2px solid green':'1px solid black'}}
         key={i}>{item} 
         <Button onClick={()=>onDelete(i)}style={btnStyle}variant="danger">Delete</Button></li>
        )})

    return (
        <div>
            <ListGroup as="ul">
                 {itemShow}
            </ListGroup>
        </div>
    )
} 

1 Ответ

1 голос
/ 19 марта 2020

Toggle Single

Обновление handleToggle для получения переданного ему индекса и сохранения его в состоянии вместо логического значения.

App.js

this.state={
  ...,
  selected: null,
}

handleToggle (selected) {
  console.log("toggled index", selected);
  console.log("selected state", this.state.selected);
  this.setState({ selected });
}

Обновление сопоставленных элементов для сравнения выбранного индекса с текущим индексом отображаемого элемента.

Results.js

props.items.map((item, i) => {
  const isSelected = selected === i;
  return (
    <li
      key={i}
      onClick={() => handleToggle(i)}
      class="list-group-item"
      style={{
        textDecorationLine: isSelected ? "line-through" : "none",
        textDecorationStyle: isSelected ? "solid" : "none",
        border: isSelected ? "2px solid green" : "1px solid black"
      }}
    >
      {item}
      <Button onClick={() => onDelete(i)} style={btnStyle} variant="danger">
        Delete
      </Button>
    </li>
  );
});

Переключить несколько

Обновите handleToggle, чтобы взять переданный ему индекс и сохранить его в состоянии вместо логического значения. Измените состояние selected на объект индексов в качестве ключей и выберите значение true / false в качестве значения.

App.js

this.state={
  ...,
  selected: {},
}

handleToggle (index) {
  console.log("toggled index", index);
  console.log("selected state", this.state.selected);
  this.setState(prevState => {
    // copy state and update index
    const selected = {...prevState.selected};
    selected[index] = !selected[index];
    return { selected };
  });
}

Обновите сопоставленные элементы, чтобы извлечь выбранное значение из текущий индекс i отображаемого элемента.

Results.js

props.items.map((item, i) => {
  const isSelected = selected[i];
  return (
    <li
      key={i}
      onClick={() => handleToggle(i)}
      className="list-group-item"
      style={{
        textDecorationLine: isSelected ? "line-through" : "none",
        textDecorationStyle: isSelected ? "solid" : "none",
        border: isSelected ? "2px solid green" : "1px solid black"
      }}
    >
      {item}
      <Button onClick={() => onDelete(i)} style={btnStyle} variant="danger">
        Delete
      </Button>
    </li>
  );
});

Edit blissful-curie-1hrxo

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...