#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
Я предполагаю, что вы можете понять, что делает код… если нет, спросите…