Как я могу отображать динамическое состояние в реакции? - PullRequest
0 голосов
/ 27 июня 2019

Я создаю state динамически, но мне нужно использовать это state в моем рендере.

Смотрите мою проблему:

handleChange = (name, checked) => {
  this.setState({
    [name]: checked,
  })
}

Итак, в моем render как я могу отобразить мое состояние [name]? (Я не знаю его имени, так как оно динамическое)

render(){

  console.log(this.state....?)

  return(
    <p>Hello</p>
  )
}

Моя функция handleChange вызывается, когда я проверяю свой checbkox. Итак, если у меня есть 5, 10, 20 флажков, как я могу отобразить мое состояние [name]?

----> ОБНОВЛЕНИЕ - ПОЛНЫЙ КОД <---- </strong>
Я использую свойство hover для отображения моего флажка:

CSS с использованием пользовательского интерфейса:

  hideCheckbox: {
    display: 'none',
  },
  showCheckbox: {
    display: 'initial',
  },

Мой основной класс:

export class Item extends Component {

state = { 
  isHovering: true,
  checkboxChecked: false,
}

handleGetCardSelected = (id, checked) => { 
 //Here I set isHovering to display my checkbox
 //checkboxChecked is a control variable to always display the checkbox if it's checked

  if(checked){
    this.setState({
      isHovering: !this.state.isHovering,
      checkboxChecked: true,
    })

  } else {
    this.setState({
      checkboxChecked: false,
    })
  }
}

handleMouseHover = () => {
  if(!this.state.checkboxChecked){
    this.setState(this.toggleHoverState);
  }
}

toggleHoverState = (state) => {
  return {
    isHovering: !state.isHovering,
  };
}
return(
 <div 
   onMouseEnter={this.handleMouseHover} 
   onMouseLeave={this.handleMouseHover}
  >
   <div className={`
     ${this.state.isHovering && classes.hideCheckbox }
     ${this.state.checkboxChecked && classes.showCheckbox}
    `}>
      <CheckBoxCard handleGetCardSelected={this.handleGetCardSelected}/>
    </div>
  </div>

 <div 
   onMouseEnter={this.handleMouseHover} 
   onMouseLeave={this.handleMouseHover}
  >
   <div className={`
     ${this.state.isHovering && classes.hideCheckbox }
     ${this.state.checkboxChecked && classes.showCheckbox}
    `}>
      <CheckBoxCard handleGetCardSelected={this.handleGetCardSelected}/>
    </div>
  </div>

 <div 
   onMouseEnter={this.handleMouseHover} 
   onMouseLeave={this.handleMouseHover}
  >
   <div className={`
     ${this.state.isHovering && classes.hideCheckbox }
     ${this.state.checkboxChecked && classes.showCheckbox}
    `}>
      <CheckBoxCard handleGetCardSelected={this.handleGetCardSelected}/>
    </div>
  </div>
 )
 }

Моя CheckboxCard:

import React from 'react';
import { makeStyles, withStyles } from '@material-ui/core/styles';
import { Checkbox } from '@material-ui/core';
const GreenCheckbox = withStyles({
  root: {
    color: '#43a04754',
    '&$checked': {
      color: '#43a047',
    },
    '&:hover': {
      color: '#43a047',
      backgroundColor: 'initial',
    },
  },
  checked: {},
})(props => <Checkbox color="default" {...props} />);

export default function CheckBoxCard(props){
  const [state, setState] = React.useState({
    idItem: false,
  });

  const handleCheckbox = name => event => {
    setState({ ...state, [name]: event.target.checked });

    let id = name
    let checked = event.target.checked
    props.handleGetCardSelected(id, checked)
  };

  return(
    <GreenCheckbox
      checked={state.idItem}
      onChange={handleCheckbox('idItem')}
      value="idItem"
      inputProps={{
        'aria-label': 'primary checkbox',
      }}
    />
  );
}

По умолчанию мой флажок скрыт, потому что мой state isHovering имеет значение true, поэтому установлена ​​переменная css hideCheckbox ('display: none').

Если я наведу курсор на элемент, он будет назван handleMouseHover, и появится флажок!

Если я установил флажок, для true установлено checkboxChecked, и теперь я всегда отображаю свой флажок! Но, если у меня два или более элемента, отображается все флажок, потому что checkboxChecked является уникальным элементом!

Итак, мой checkboxChecked должен быть динамичным и для каждого предмета! Таким образом, если checked, будет отображаться только этот флажок. Остальные нет!

Для первого элемента:
${this.state.checkboxCheckedITEM1 && classes.showCheckbox}

Для второго элемента:
${this.state.checkboxCheckedITEM2 && classes.showCheckbox}

Для второго элемента:
${this.state.checkboxCheckedITEM3 && classes.showCheckbox}

Я обновляю свой код в песочнице: https://codesandbox.io/embed/material-demo-16t91?fontsize=14

Как я могу это сделать?

Ответы [ 5 ]

0 голосов
/ 27 июня 2019

Вы можете посмотреть на Object.keys(), но если в будущем вам потребуется обрабатывать более одного состояния, итерация, похоже, не решит проблему.

Вы могли бы также дать ему префикс [name_${name}]: checked, но не рекомендовали бы это вообще.

Если это не проблема, используйте объект, и вы получите полный контроль над ним.

this.setState({
  something: {
    name,
    checked  
  },
})
0 голосов
/ 27 июня 2019

При этом:

this.state[name]

0 голосов
/ 27 июня 2019

Вы можете отфильтровать свой объект, чтобы получить только проверенные имена.

Object.keys(this.state).filter(name => this.state[name]);
0 голосов
/ 27 июня 2019

Если у вас есть конечный список checkbox компонента

render() {
  return (
    <div>
      <Checkbox
        handleChange={() => this.handleChange('abc', !this.state[abc])}
        className={this.state['abc'] ? 'checked-class' : '' }
      />
    </div>
  )
}

В другой ситуации, когда вы отображаете список динамических флажков.

componentDidMount() {
  //Calling API to return dynamic list of checkboxes, and dump them into a state
  this.setState({ listOfCheckboxes });
}

Тогда в вашем render методе вы будете использовать .map function

render() {
  return (
    <div>
    {
      this.state.listOfCheckboxes.map(x => (
        <Checkbox
          handleChange={() => this.handleChange(x.name, !this.state[x.name]) }
          className={this.state[x.name] ? 'checked-class' : '' }
        />))
    }
    </div>
  )
}
0 голосов
/ 27 июня 2019

Итак, если у меня есть 5, 10, 20 флажков, как я могу отобразить свое состояние [имя]?

Я думаю, что разумный способ сделать это - вложить компоненты.Иметь абстрактный родительский компонент, который отображает дочерний компонент только после того, как имя становится доступным.Используя этот шаблон, ваша проблема может быть решена.

Ознакомьтесь с этой полезной статьей

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