флажок обновления установлен в родительском

#javascript #reactjs

#javascript #reactjs

Вопрос:

Родительский компонент

 class Parent extends Component {
 constructor(props) {
        super(props);
        this.state = {
        checkedView:[
                {id: 1, value: "A", isChecked: false},
                {id: 2, value: "B", isChecked: true},
                {id: 3, value: "C", isChecked: true},
                {id: 4, value: "D", isChecked: true}
            ],
        }
    }
   handleCheck=(e)=>{
       this.setState({ isChecked: e.target.checked});
   }
   render(){
     return(
        <div>
             <Selection checkedView={this.state.checkedView} handleCheck={this.handleCheck} />
             <Content checkedView={this.state.checkedView} />
        </div>
     );
   }
}
  

Компонент выбора

 class Selection extends Component {
  constructor(props) {
    super(props)
    this.state = {
      checkedView: this.props.checkedView
    }
  }

  handleCheck = (event) => {
    let checkedView = this.props.checkedView;
      checkedView.forEach( item => {
        if(item.value === event.target.value){
          item.isChecked = event.target.checked
        }
      })
    this.setState({
      checkedView: checkedView
    })
    this.props.handleCheck(event)
  }  

  render() {
    return (
      <div className="">
        <ul className="morefeatures">{
          this.props.checkedView.map((selection, index) => {
            return (<CheckBox  key={index} handleCheck={this.handleCheck} {...selection}  />)
          })
        }
        </ul>
      </div>
    );
  }
}
  

ФЛАЖОК

 export const CheckBox = props => {
    return (
      <li>
       <input key={props.id} onClick={props.handleCheck} type="checkbox" checked={props.isChecked} value={props.value} /> {props.value}
      </li>
    )
}
  

У меня есть родительский компонент, который управляет содержимым, и компонент выбора должен иметь возможность обновлять свои изменения в родительском компоненте, чтобы другие дочерние компоненты могли получить доступ к значению флажка.
Когда установлен один (или несколько) флажков, компонент содержимого получает сигнал для отображения соответствующего содержимого, что-то вроде этого

Отмеченный IsChecked не меняет своего статуса независимо от того, установлен флажок или нет.

Итак, как я должен изменить код, чтобы IsChecked действительно работал?????

Ответ №1:

Вы не обновляете правильное состояние. this.setState({ isChecked: e.target.checked}); добавляет новую переменную isChecked в состояние. Что вы хотите, так это найти правильную запись внутри checkedView и обновить этот объект. Я бы передал id флажку и далее onClick , я бы вызвал handleChecked , который получает не только событие, но и id флажок. В handleChecked затем вы можете найти правильный флажок на основе id и соответствующим образом обновить его.

В родительском:

    handleCheck=(id, checked)=>{
       // deep copy old state (check out lodash for a nicer deepCopy)
       const checkedView = JSON.parse(JSON.stringify(this.state.checkedView));
       const checkBox = checkedView.find(view => view.id === id);
       checkBox.isChecked = checked;
       // update whole object of new state
       this.setState(checkedView);
   }
  

При выборе:

!Предупреждение! Вы изменяли реквизиты, никогда не обновляйте реквизиты, это работа родителя. Вам также не нужно переводить checkedView в состояние выбора, вы получаете его как prob, просто передайте его.

 handleCheck = (event, id) => {
    this.props.handleCheck(id, e.target.checked)
}  
  
 class Selection extends Component {
  constructor(props) {
    super(props)
  }

  handleCheck = (event, id) => {
    this.props.handleCheck(id, e.target.checked)
  }  

  render() {
    return (
      <div className="">
        <ul className="morefeatures">{
          this.props.checkedView.map((selection) => {
            return (<CheckBox key={selection.id} handleCheck={this.handleCheck} {...selection}  />)
          })
        }
        </ul>
      </div>
    );
  }
}
  

В Checkbox оберните проверку handleCheck, чтобы передать ему как событие, так и идентификатор для идентификации флажка.

 <input onClick={(e) => props.handleCheck(e, props.id)} type="checkbox" checked={props.isChecked} value={props.value} /> {props.value}
  

Комментарии:

1. Спасибо за решение, но мне все еще нужна помощь. Я заменил на ваш код, но тогда флажки не могут быть установлены / сняты. Итак, я изменил setState на this.setState({checkedView: checkedView}); но его статус по-прежнему не изменен, checked остается проверенным из Inspect

2. Конечно! Вы видите какие-либо ошибки в консоли? Не стесняйтесь также попробовать версию от SakoBu. Я пытался сохранить вашу общую структуру кода как есть, но версия, предложенная СакоБу, очень чистая. Возможно, вы захотите попробовать.

Ответ №2:

Если я понимаю ваш вопрос, я думаю, это то, что вы ищете — ваша архитектура и логика немного не в порядке, и вы загнали себя в угол … — Два компонента (родительский и дочерний)

Вот ваш родительский элемент: (сохраняет состояние и все методы, которые им манипулируют)

 export default class Parent extends React.Component {
    state = {
        checkedView: [
            { id: 1, value: 'A', isChecked: false },
            { id: 2, value: 'B', isChecked: true },
            { id: 3, value: 'C', isChecked: true },
            { id: 4, value: 'D', isChecked: true }
        ]
    };

    handleCheck = (id) => {
        this.setState({
            checkedView: this.state.checkedView.map((item) => {
                if (item.id === id) {
                    return {
                        ...item,
                        isChecked: !item.isChecked
                    };
                } else {
                    return item;
                }
            })
        });
    };

    render() {
        return (
            <div>
                {this.state.checkedView.map((item) => (
                    <Child key={item.id} item={item} handleCheck={this.handleCheck} />
                ))}
            </div>
        );
    }
}
  

Вот ваш дочерний элемент:

импортируйте React из ‘react’;

 export default function Child({ item, handleCheck }) {
    return (
        <div onClick={() => handleCheck(item.id)}>
            {item.value}
            <input type='checkbox' defaultChecked={item.isChecked} />
        </div>
    );
}
  

Вот живая демонстрация:https://stackblitz.com/edit/react-ddqwpb?file=src/App.js

Я предполагаю, что вы можете понять, что делает код… если нет, спросите…